效果图:
要求:1.获取应用并展示,上下滑动带动画
2.未加锁中点击"锁"图标动画删除该条目,并添加至 程序锁 数据库(存放已加锁应用)
3.已加锁中点击"锁"图标动画删除该条目,并将当前应用从 程序锁 中删除
上代码:
首先编写页面:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="pl.zyqj.zz.programlock.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#6600ff00"
android:gravity="center"
android:padding="8dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_unlock"
android:background="@drawable/tab_left_pressed"
android:gravity="center"
android:text="未加锁"
android:textColor="#ffffff" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/tab_right_default"
android:gravity="center"
android:text="已加锁"
android:id="@+id/tv_locked"
android:textColor="#ffffff" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_content"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</LinearLayout>
</LinearLayout>
MainActivity.java
public class MainActivity extends FragmentActivity implements View.OnClickListener {
private TextView tvUnLock;
private TextView tvLocked;
private UnLockFragment unlockFragment;
private LockedFragment lockedFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvUnLock = (TextView) findViewById(R.id.tv_unlock);
tvLocked = (TextView) findViewById(R.id.tv_locked);
tvUnLock.setOnClickListener(this);
tvLocked.setOnClickListener(this);
unlockFragment = new UnLockFragment();
lockedFragment = new LockedFragment();
// 获得fragment管理器
FragmentManager fragmentManager = getSupportFragmentManager();
// 开启事务
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
// 使用 fragment 替换 指定的布局中所有的子view
beginTransaction.replace(R.id.ll_content, unlockFragment);
// 提交
beginTransaction.commit();
}
/**
* fragment 的使用步骤:
* 一:先在布局文件中,为fragment指定一个显示的区域
* 二:让activiy改为继承自 FragmentActivity
* 三:显示fragment
// 获得fragment管理器
FragmentManager fragmentManager = getSupportFragmentManager();
// 开启事务
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
// 使用 fragment 替换 指定的布局中所有的子view
beginTransaction.replace(R.id.ll_content, unlockFragment);
// 提交
beginTransaction.commit();
*
* 注意事件:如果关联了v4包的源码,记着把v4包加入到apk安装包中
*/
@Override
public void onClick(View v) {
// 获得fragment管理器
FragmentManager fragmentManager = getSupportFragmentManager();
// 开启事务
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
switch (v.getId()) {
case R.id.tv_unlock:
// 使用 fragment 替换 指定的布局中所有的子view
beginTransaction.replace(R.id.ll_content, unlockFragment);
tvUnLock.setBackgroundResource(R.drawable.tab_left_pressed);
tvLocked.setBackgroundResource(R.drawable.tab_right_default);
break;
case R.id.tv_locked:
// 使用 fragment 替换 指定的布局中所有的子view
beginTransaction.replace(R.id.ll_content, lockedFragment);
tvUnLock.setBackgroundResource(R.drawable.tab_left_default);
tvLocked.setBackgroundResource(R.drawable.tab_right_pressed);
break;
}
// 提交
beginTransaction.commit();
}
}
获取应用数据:AppUtils.java
public class AppUtils {
/**
* 获得手机中安装的所有的应用的信息
* @param ctx
* @return
*/
public static List<AppInfoBean> getAllAppInfo(Context ctx){
List<AppInfoBean> allAppInfo = new ArrayList<AppInfoBean>();
// 包管理器,管理手机 中所有的APK 安装包
PackageManager pm = ctx.getPackageManager(); // pm project manager 项目经理
List<PackageInfo> installedPackages = pm.getInstalledPackages(0);
for (PackageInfo packageInfo : installedPackages) {
// PackageInfo 包含AndroidManifest清单文件中,所有的信息
// ApplicationInfo 包含 AndroidManifest清单文件中 , application中的所有的信息
ApplicationInfo applicationInfo = packageInfo.applicationInfo;
AppInfoBean appBean = new AppInfoBean();
allAppInfo.add(appBean); // 添加至集合
// 设置包名
appBean.packageName = packageInfo.packageName;
// 获得应用名称
appBean.appName = applicationInfo.loadLabel(pm).toString();
// 应用图标
appBean.appIcon = applicationInfo.loadIcon(pm);
// applicationInfo.dataDir; // /data/data/包名 路径
String apkPath = applicationInfo.sourceDir; // 该应用apk 的路径
// System.out.println(appBean.appName+ " : "+apkPath);
// 为apkPath 赋值
appBean.apkPath = apkPath;
File apkFile = new File(apkPath);
appBean.appSize = apkFile.length();
// 根据路径判断是否是系统应用
if(apkPath.startsWith("/data")){ // 用户应用
appBean.isSys = false;
System.out.println(appBean.appName+" 根据 路径 值判断,是用户应用");
}else{
// 系统应用
appBean.isSys = true;
System.out.println(appBean.appName+" 根据 路径 值判断,是系统应用");
}
// 根据flag 值来判断是否是系统应用
// 如果不等于0,说明批配成功,那么当前应用,拥有该 FLAG 值标注的属性
if((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)!=0 ){
System.out.println(appBean.appName+" 根据 flag 值判断,是系统应用");
}else{
System.out.println(appBean.appName+" 根据 flag 值判断,是用户应用");
}
if((applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE)!=0){ //
appBean.isInSd = true;
}else{
appBean.isInSd = false;
}
}
SystemClock.sleep(500); // 休眠2秒,模拟耗时的情况
return allAppInfo;
}
未加锁,已加锁 中做操作
UnLockFragment.java
public class UnLockFragment extends Fragment {
private TextView tvDesc;
private ListView listView;
private AppLockDao lockDao;
private boolean isAnim;
/**
* 未加锁的应用集合
*/
private List<AppInfoBean> unlockAppList;
private ProgressDialog proDlg;
private MyAdapter adapter;
@Override
/**
* Fragment 就是对一个view 和这个 view 的所有逻辑处理 封装在一个类中
* 创建一个view
*/
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
lockDao = AppLockDao.getInsantce(getActivity());
View view = inflater.inflate(R.layout.fragment_unlock, null);
tvDesc = (TextView) view.findViewById(R.id.tv_desc);
listView = (ListView) view.findViewById(R.id.listView);
proDlg = new ProgressDialog(getActivity());
proDlg.setMessage("玩命加载中...");
fillData();
initListener();
return view;
}
private void initListener() {
listView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL
|| scrollState == OnScrollListener.SCROLL_STATE_FLING) {
isAnim = true;
} else {
isAnim = false;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
}
private void fillData() {
proDlg.show();
new Thread() {
public void run() {
unlockAppList = new ArrayList<AppInfoBean>();
//获取应用
List<AppInfoBean> allAppInfo = AppUtils.getAllAppInfo(getActivity());
for (AppInfoBean app : allAppInfo) {
if (lockDao.isLockApp(app.packageName)) {//查询数据库中是否包名此包名的应用
// 是需要锁定的 包含:说明是锁定的程序
} else {
// 没有锁定的 不包含:不需要锁定的程序
unlockAppList.add(app);
}
}
handler.sendEmptyMessage(88);
}
;
}.start();
}
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
proDlg.dismiss();
// 显示listView
adapter = new MyAdapter();
listView.setAdapter(adapter);
}
;
};
private class ViewHolder {
public TextView tvName;
public ImageView ivIcon;
public ImageView ivUnLock;
}
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
tvDesc.setText("未加锁应用:" + unlockAppList.size() + "个");
return unlockAppList.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view;
ViewHolder vh;
if (convertView == null) {
view = View.inflate(getActivity(), R.layout.list_item_unlock_fragment, null);
vh = new ViewHolder();
// 找到子view , 并打包
vh.tvName = (TextView) view.findViewById(R.id.tv_name_list_item);
vh.ivIcon = (ImageView) view.findViewById(R.id.iv_icon_list_item);
vh.ivUnLock = (ImageView) view.findViewById(R.id.iv_unlock_fragment);
// 背包
view.setTag(vh);
} else {
view = convertView;
vh = (ViewHolder) view.getTag();
}
AppInfoBean app = unlockAppList.get(position);
vh.ivIcon.setBackgroundDrawable(app.appIcon);
vh.tvName.setText(app.appName);
vh.ivUnLock.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 当前条目做平移动画
// X方向从0到100% ,Y方向保持不变
TranslateAnimation ta = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
ta.setDuration(500);
// ta.setFillAfter(true); // 动画完成后,保持完成的状态
View itemView = (View) v.getParent(); // v.getParent() 获得V的父view
itemView.startAnimation(ta); // 向系统发布做动画的命令
/**
* 添加动画的监听,当动画执行完之后,再删除并刷新条目,否则条目会复用混论,同时 //ta.setFillAfter(true); // 动画完成后,保持完成的状态
*/
ta.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
// 将当前应用添加至程序锁 数据库
lockDao.addAppLock(unlockAppList.get(position).packageName);
// 从未加锁列表中删除该条目
unlockAppList.remove(position);
notifyDataSetChanged(); // 刷新列表
}
});
}
});
if (isAnim) {
// 课外题,让listView 仅在上下滑动时,执行条目动画
TranslateAnimation ta = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, -1, Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
ta.setDuration(500);
view.startAnimation(ta);
}
return view; // 如果返回 null ,发报异常,并且,异常中,只有系统代码,没有我们的代码
}
}
}
LockedFragment.java
public class LockedFragment extends Fragment {
private TextView tvDesc;
private ListView listView;
private AppLockDao lockDao;
/**
* 已加锁的应用集合
*/
private List<AppInfoBean> lockedAppList;
private ProgressDialog proDlg;
private MyAdapter adapter;
@Override
/**
* Fragment 就是对一个view 和这个 view 的所有逻辑处理 封装在一个类中
* 创建一个view
*/
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
lockDao = AppLockDao.getInsantce(getActivity());
View view = inflater.inflate(R.layout.fragment_locked, null);
tvDesc = (TextView) view.findViewById(R.id.tv_desc);
listView = (ListView) view.findViewById(R.id.listView);
proDlg = new ProgressDialog(getActivity());
proDlg.setMessage("玩命加载中...");
fillData();
return view;
}
private void fillData() {
proDlg.show();
new Thread() {
public void run() {
lockedAppList = new ArrayList<AppInfoBean>();
List<AppInfoBean> allAppInfo = AppUtils.getAllAppInfo(getActivity());
for (AppInfoBean app : allAppInfo) {
if (lockDao.isLockApp(app.packageName)) {
// 是需要锁定的
lockedAppList.add(app);
} else {
// 没有锁定的
}
}
handler.sendEmptyMessage(88);
};
}.start();
}
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
proDlg.dismiss();
// 显示listView
adapter = new MyAdapter();
listView.setAdapter(adapter);
}
;
};
private class ViewHolder {
public TextView tvName;
public ImageView ivIcon;
public ImageView ivLocked;
}
private class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
tvDesc.setText("已加锁应用:" + lockedAppList.size() + "个");
return lockedAppList.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view;
ViewHolder vh;
if (convertView == null) {
view = View.inflate(getActivity(), R.layout.list_item_locked_fragment, null);
vh = new ViewHolder();
// 找到子view , 并打包
vh.tvName = (TextView) view.findViewById(R.id.tv_name_list_item);
vh.ivIcon = (ImageView) view.findViewById(R.id.iv_icon_list_item);
vh.ivLocked = (ImageView) view.findViewById(R.id.iv_locked_fragment);
// 背包
view.setTag(vh);
} else {
view = convertView;
vh = (ViewHolder) view.getTag();
}
AppInfoBean app = lockedAppList.get(position);
vh.ivIcon.setBackgroundDrawable(app.appIcon);
vh.tvName.setText(app.appName);
vh.ivLocked.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 当前条目做平移动画
// X方向从0到100% ,Y方向保持不变
TranslateAnimation ta = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, -1,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
ta.setDuration(500);
// ta.setFillAfter(true); // 动画完成后,保持完成的状态
View itemView = (View) v.getParent(); // v.getParent() 获得V的父view
itemView.startAnimation(ta); // 向系统发布做动画的命令
ta.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
// 将当前应用从程序锁中删除
lockDao.deleteAppLock(lockedAppList.get(position).packageName);
// 从未加锁列表中删除该条目
lockedAppList.remove(position);
notifyDataSetChanged(); // 刷新列表
}
});
}
});
// 课外题,让listView 仅在上下滑动时,执行条目动画
TranslateAnimation ta = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, -1, Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
ta.setDuration(500);
// view.startAnimation(ta);
return view; // 如果返回 null ,发报异常,并且,异常中,只有系统代码,没有我们的代码
}
}
}
展示数据库:
AppLockDbHelper.java
/**
* 程序锁数据库
*/
public class AppLockDbHelper extends SQLiteOpenHelper{
public AppLockDbHelper(Context context, String name, int version) {
super(context, name, null, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
// 创建程序锁 表,存储所有的需要被锁定的应用的(包名) 作为唯一标识
db.execSQL("create table applock(_id integer primary key autoincrement, package_name varchar(40));");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
AppLockDao.java
/**
* 操作的工具类 单例的
*/
public class AppLockDao {
private Context ctx;
private AppLockDao(Context ctx){
this.ctx = ctx;
dbHelper = new AppLockDbHelper(ctx, "app_lock.db", 1);
}
private static AppLockDao instance;
public static synchronized AppLockDao getInsantce(Context ctx){
if(instance == null){
instance = new AppLockDao(ctx);
}
return instance;
}
private AppLockDbHelper dbHelper;
private String table_app_lock = "applock";
/**
* 定义一个指向程序锁数据库的URI
*/
// private Uri uri = Uri.parse("content://zz.itcast.cn.applock");
/**
* 添加程序锁 已加锁
* @param packageName
*/
public void addAppLock(String packageName){
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("package_name", packageName);
db.insert(table_app_lock, null, values);
}
/**
* 删除程序锁
* @param packageName
*/
public void deleteAppLock(String packageName){
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete(table_app_lock, " package_name = ? ", new String[]{packageName});
}
/**
* 判断指定包名的应用是否需要被锁定 查
* @param packageName
* @return
*/
public boolean isLockApp(String packageName){
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.query(table_app_lock, null," package_name = ? ", new String[]{packageName}, null, null, null);
boolean isAppLock = false;
if(cursor.moveToNext()){ // 如果查到内容,移动成功
isAppLock = true;
}
cursor.close();
return isAppLock;
}
/**
* 获得所有需要被锁定的应用
* @return
*/
public List<String> getAllAppLock(){
ArrayList<String> appLocks = new ArrayList<String>();
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.query(table_app_lock, null, null, null, null, null, null);
// cursor 默认指向第一行的上一行
while(cursor.moveToNext()){
String packageName = cursor.getString(1); // 总共二列,包名那列,下标为1
appLocks.add(packageName);
}
cursor.close();
return appLocks;
}
}
AppInfoBean.java
public class AppInfoBean {
/**
* 应用的包名
*/
public String packageName;
public String appName;
public Drawable appIcon;
/**
* 应用的大小,即APK安装包的大小
*/
public long appSize;
/**
* 判断是否是安装在SD卡中
*/
public boolean isInSd;
/**
* 判断是否是系统应用
*/
public boolean isSys;
/**
* APK文件的路径
*/
public String apkPath;
}
代码中注释的已经很详细,请参看
源码:http://download.csdn.net/download/lijinweii/9951238