最近做功能开发时候需要显示当前手机安装的app信息.这里我使用Dialog来显示.截图如下:
如上截图所示,这个dialog显示了当前手机安装的app,当点击一个菜单项时候就会在上面显示一个上锁的图案(如上图:视频/相机/联系人).这时一个可以对app上锁的设计界面.
首先来看看dialog的创建:
private void Init_create_dialog(){ if(null == show_app_dialog){ show_app_dialog = new Dialog(getActivity()){ protected void onStop() { super.onStop(); FingerPrint_Utils.FingerPrint_save_LockApp(getActivity()); } }; show_app_dialog.setContentView(R.layout.finger_gride_app_choose); show_app_dialog.setTitle(R.string.finger_print_set_unlock_app_title); GridView gvApp = ((GridView)show_app_dialog.findViewById(R.id.gv_app)); final List<FingerPrintApplicationInfo> list = FingerPrint_Utils.get_LockApplicationInfoList(); gvApp.setAdapter(new AppChooseAdapter(list)); gvApp.setOnItemClickListener(new AdapterView.OnItemClickListener(){ public void onItemClick(AdapterView<?> parent, View view, int position, long id){ FingerPrintApplicationInfo Fingerappinfo = (FingerPrintApplicationInfo)parent.getItemAtPosition(position); ResolveInfo appinfo = Fingerappinfo.launcher_activity; //CharSequence name = appinfo.loadLabel(package_manager); AppChooseAdapter.ViewHolder hold = (AppChooseAdapter.ViewHolder) view.getTag(); if(Fingerappinfo.locked){ hold.app_icon.setImageResource(0); Fingerappinfo.locked = false; FingerPrint_Utils.FingerPrint_Dele_LockApp(appinfo.activityInfo.packageName);//activityInfo.packageName }else{ hold.app_icon.setImageResource(R.drawable.lock_app_icon); Fingerappinfo.locked = true; FingerPrint_Utils.FingerPrint_AddNew_LockApp(appinfo.activityInfo.packageName); } //selected_str = appinfo.packageName; //if(DEBUG) Log.d(TAG,"FingerPrintSettingMain: name="+name+"; appinfo.packageName="+appinfo.packageName); //show_app_dialog.dismiss(); } }); /* show_app_dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { public void onDismiss(final DialogInterface dialog) { FingerPrint_Utils.FingerPrint_save_LockApp(getActivity()); } });*/ show_app_dialog.getWindow().setCloseOnTouchOutside(true); show_app_dialog.setCanceledOnTouchOutside(true); } }
再看看其layout的文件:finger_gride_app_choose.xml
<?xml version="1.0" encoding="utf-8"?><GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gv_app" android:layout_width="match_parent" android:layout_height="match_parent" android:numColumns="3" android:padding="10dp" android:verticalSpacing="10dp" android:horizontalSpacing="10dp" android:gravity="center" />实际上就是一个GridView,所以整个界面的重点其实就是这个GridView的Adapter设计.所以看看这个Adapter:AppChooseAdapter
class AppChooseAdapter extends BaseAdapter{ private List<FingerPrintApplicationInfo> applicationInfos; private PackageManager pm; class ViewHolder { TextView app_name; ImageView app_icon; //ImageView locked_icon; } public AppChooseAdapter(List<FingerPrintApplicationInfo> list){ applicationInfos = list; } public int getCount(){ return applicationInfos.size(); } public Object getItem(int position){ return applicationInfos.get(position); } public long getItemId(int position){ return position; } public View getView(int position, View view, ViewGroup parent){ //PackageManager pm = package_manager; final ViewHolder hold; if (view == null){ if(DEBUG) Log.d(TAG,"AppChooseAdapter: (view == null) position="+position); Context context = parent.getContext(); view = LayoutInflater.from(context).inflate(R.layout.item_app_gride, null); hold = new ViewHolder(); hold.app_icon = (ImageView)view.findViewById(R.id.iv_icon); //hold.locked_icon = (ImageView)view.findViewById(R.id.lock_statu_img); hold.app_name = (TextView)view.findViewById(R.id.tv_name); view.setTag(hold); }else{ if(DEBUG) Log.d(TAG,"AppChooseAdapter: (view != null) position="+position); hold = (ViewHolder) view.getTag(); } final int curr_position = position; view.post(new Runnable() { public void run() { //ViewHolder hold = (ViewHolder) view.getTag(); PackageManager pm = package_manager; if(hold != null){ FingerPrintApplicationInfo aInfo = (FingerPrintApplicationInfo)applicationInfos.get(curr_position); String package_name = aInfo.launcher_activity.activityInfo.packageName;//aInfo.app.packageName; if(aInfo.locked){ hold.app_icon.setImageResource(R.drawable.lock_app_icon); }else{ hold.app_icon.setImageResource(0); } hold.app_name.setText(aInfo.launcher_activity.loadLabel(pm)); hold.app_icon.setBackgroundDrawable(aInfo.launcher_activity.loadIcon(pm)); //image.setImageDrawable(aInfo.app.loadIcon(pm)); } } }); return view; } }上面已经贴出了基本所有代码.下面做一下说明:
(1)每一次显示这个dialog都会一点延时,如何解决这个问题.我有了两个办法来解决:
首先,加载手机安装的app信息,我会在显示这个dialog之前就加载好,然后只需要通过FingerPrint_Utils.get_LockApplicationInfoList()来获取就可以.其中加载app信息使用AsyncTask来完成的.AsyncTask的使用比较简单了,这里我只给出加载app的信息的代码:
private static ArrayList<FingerPrintApplicationInfo> getInstalledLaunchableApps(FingerPrintSettingMain.AppLabelComparator mcomparator){ final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); PackageManager pm = mcomparator.getPackageManager(); List list = pm.queryIntentActivities(mainIntent, 0);//查询获取安装的所有app ArrayList<FingerPrintApplicationInfo> array = new ArrayList<FingerPrintApplicationInfo>(); ArrayList<FingerPrintApplicationInfo> array1 = new ArrayList<FingerPrintApplicationInfo>(); int size = list.size(); String[] APP_DELE = ALL_APP_DELE_PACKAGENAME; String[] LOCK_APP_DELE = LOCK_APP_DELE_PACKAGENAME; //Log.d(TAG,"getInstalledLaunchableApps: size="+size); boolean has = false; String locked_packagename = app_locked_PackageName!=null?app_locked_PackageName.toString():null; ResolveInfo curr; for (int i=0; i<size; i++){ has = false; curr = (ResolveInfo)list.get(i); if(null == curr){ continue; } String str = curr.activityInfo.packageName; if(!wei_xing_install && 0 == weixing_package.compareTo(str)){//检测是否安装微信 wei_xing_install = true; } Iterator iterator = array.iterator(); if(null != APP_DELE){ for(int j = 0; j < APP_DELE.length; j++){//有一些app不需要在这里显示,过滤掉一些app if(APP_DELE[j].compareTo(str) == 0){ has = true; } } } if(has) continue; FingerPrintApplicationInfo app = new FingerPrintApplicationInfo(); app.launcher_activity = curr; if(locked_packagename != null && locked_packagename.indexOf(str)>-1){ app.locked = true; } array.add(app); if(null != LOCK_APP_DELE){ for(int n = 0; n < LOCK_APP_DELE.length; n++){ if(LOCK_APP_DELE[n].compareTo(str) == 0){ has = true; } } } if(has) continue; array1.add(app); } Collections.sort(array, mcomparator); Collections.sort(array1, mcomparator); if(array1 != null){ unlock_pacakegename_app_dele = array1; } return array; }即使在显示dialog之前就加载好app信息,在显示dialog时候也会有一个较长的延迟,这是因为加载每一个app的icon和text_name也是需要时间的.所以,如上面的代码AppChooseAdapter的getView中我使用了view.post(new Runnable())的方法来加载显示的信息.
(2)如何实现点击一个app菜单选项时候能够在上面显示一个锁的图像.仔细看上面的源码可以发现,这里我使用了ImageView的image和背景来做的.首先ImageView的背景图片用来显示app的icon,而ImageView的image来显示是锁的图片.如果上锁则这个ImageView就设置image:
hold.app_icon.setImageResource(R.drawable.lock_app_icon);
否则:
hold.app_icon.setImageResource(0);
版权声明:本文为博主原创文章,未经博主允许不得转载。