【开源中国 APP 全新上线】“动弹” 回归、集成大模型对话、畅读技术报告”
在home节面上,当我们点击中间按键的时候,会跳转到一个下图,
在代码中是如何实现的呢?我们来找一下:
mHandleView = (HandleView) findViewById(R.id.all_apps_button); mHandleView.setLauncher(this); mHandleView.setOnClickListener(this); mHandleView.setOnLongClickListener(this);再看onclick()方法:在onclick方法中,有一下代码
else if (v == mHandleView) { if (isAllAppsVisible()) { closeAllApps(true); } else { showAllApps(true); }我们再找一下 showAllApps()方法
void showAllApps(boolean animated) { mAllAppsGrid.zoom(1.0f, animated); ((View) mAllAppsGrid).setFocusable(true); ((View) mAllAppsGrid).requestFocus(); // TODO: fade these two too mDeleteZone.setVisibility(View.GONE); mHandleView.setVisibility(View.GONE); mPreviousView.setVisibility(View.GONE); mNextView.setVisibility(View.GONE); hotseatLeft.setVisibility(View.GONE); hotseatRight.setVisibility(View.GONE); }在上面用到了mAllAppsGrid,我们找一下这个控件:
private AllAppsView mAllAppsGrid; mAllAppsGrid = (AllAppsView)dragLayer.findViewById(R.id.all_apps_view); mAllAppsGrid.setLauncher(this); mAllAppsGrid.setDragController(dragController); ((View) mAllAppsGrid).setWillNotDraw(false); // We don't want a hole punched in our window. // Manage focusability manually since this thing is always visible ((View) mAllAppsGrid).setFocusable(false);上面代码是在Launcher.java中的setupview()方法中定义
all_apps_view是在all_app_2d.xml中定义。
你想找到AllApp2D.java中,可以找到mAllAppsGrid使用的方法,如addApps,removeApps,zoom这几个方法:
public void addApps(ArrayList<ApplicationInfo> list) { // Log.d(TAG, "addApps: " + list.size() + " apps: " + list.toString()); final int N = list.size(); for (int i=0; i<N; i++) { final ApplicationInfo item = list.get(i); int index = Collections.binarySearch(mAllAppsList, item, LauncherModel.APP_NAME_COMPARATOR); if (index < 0) { index = -(index+1); } mAllAppsList.add(index, item); } mAppsAdapter.notifyDataSetChanged(); } public void removeApps(ArrayList<ApplicationInfo> list) { final int N = list.size(); for (int i=0; i<N; i++) { final ApplicationInfo item = list.get(i); int index = findAppByComponent(mAllAppsList, item); if (index >= 0) { mAllAppsList.remove(index); } else { Log.w(TAG, "couldn't find a match for item \"" + item + "\""); // Try to recover. This should keep us from crashing for now. } } mAppsAdapter.notifyDataSetChanged(); } public void zoom(float zoom, boolean animate) { // Log.d(TAG, "zooming " + ((zoom == 1.0) ? "open" : "closed")); cancelLongPress(); mZoom = zoom; if (isVisible()) { getParent().bringChildToFront(this); setVisibility(View.VISIBLE); mGrid.setAdapter(mAppsAdapter); if (animate) { startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.all_apps_2d_fade_in)); } else { onAnimationEnd(); } } else { if (animate) { startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.all_apps_2d_fade_out)); } else { onAnimationEnd(); } } }在zoom()方法里面有mGrid.setAdapter(mAppsAdapter),在构造方法中,给adapter已经赋值。
public AllApps2D(Context context, AttributeSet attrs) { super(context, attrs); setVisibility(View.GONE); setSoundEffectsEnabled(false); mAppsAdapter = new AppsAdapter(getContext(), mAllAppsList); mAppsAdapter.setNotifyOnChange(false); }那是如何获取应用列表的呢?我们再回到Launcher.java中,在loadHotseats()中:
private void loadHotseats() { if (mHotseatConfig == null) { mHotseatConfig = getResources().getStringArray(R.array.hotseats); if (mHotseatConfig.length > 0) { mHotseats = new Intent[mHotseatConfig.length]; mHotseatLabels = new CharSequence[mHotseatConfig.length]; mHotseatIcons = new Drawable[mHotseatConfig.length]; } else { mHotseats = null; mHotseatIcons = null; mHotseatLabels = null; } TypedArray hotseatIconDrawables = getResources().obtainTypedArray(R.array.hotseat_icons); for (int i=0; i<mHotseatConfig.length; i++) { // load icon for this slot; currently unrelated to the actual activity try { mHotseatIcons[i] = hotseatIconDrawables.getDrawable(i); } catch (ArrayIndexOutOfBoundsException ex) { Log.w(TAG, "Missing hotseat_icons array item #" + i); mHotseatIcons[i] = null; } } hotseatIconDrawables.recycle(); } PackageManager pm = getPackageManager(); for (int i=0; i<mHotseatConfig.length; i++) { Intent intent = null; if (mHotseatConfig[i].equals("*BROWSER*")) { // magic value meaning "launch user's default web browser" // replace it with a generic web request so we can see if there is indeed a default String defaultUri = getString(R.string.default_browser_url); intent = new Intent( Intent.ACTION_VIEW, ((defaultUri != null) ? Uri.parse(defaultUri) : getDefaultBrowserUri()) ).addCategory(Intent.CATEGORY_BROWSABLE); // note: if the user launches this without a default set, she // will always be taken to the default URL above; this is // unavoidable as we must specify a valid URL in order for the // chooser to appear, and once the user selects something, that // URL is unavoidably sent to the chosen app. } else { try { intent = Intent.parseUri(mHotseatConfig[i], 0); } catch (java.net.URISyntaxException ex) { Log.w(TAG, "Invalid hotseat intent: " + mHotseatConfig[i]); // bogus; leave intent=null } } if (intent == null) { mHotseats[i] = null; mHotseatLabels[i] = getText(R.string.activity_not_found); continue; } if (LOGD) { Log.d(TAG, "loadHotseats: hotseat " + i + " initial intent=[" + intent.toUri(Intent.URI_INTENT_SCHEME) + "]"); } ResolveInfo bestMatch = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); List<ResolveInfo> allMatches = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); if (LOGD) { Log.d(TAG, "Best match for intent: " + bestMatch); Log.d(TAG, "All matches: "); for (ResolveInfo ri : allMatches) { Log.d(TAG, " --> " + ri); } } // did this resolve to a single app, or the resolver? if (allMatches.size() == 0 || bestMatch == null) { // can't find any activity to handle this. let's leave the // intent as-is and let Launcher show a toast when it fails // to launch. mHotseats[i] = intent; // set accessibility text to "Not installed" mHotseatLabels[i] = getText(R.string.activity_not_found); } else { boolean found = false; for (ResolveInfo ri : allMatches) { if (bestMatch.activityInfo.name.equals(ri.activityInfo.name) && bestMatch.activityInfo.applicationInfo.packageName .equals(ri.activityInfo.applicationInfo.packageName)) { found = true; break; } } if (!found) { if (LOGD) Log.d(TAG, "Multiple options, no default yet"); // the bestMatch is probably the ResolveActivity, meaning the // user has not yet selected a default // so: we'll keep the original intent for now mHotseats[i] = intent; // set the accessibility text to "Select shortcut" mHotseatLabels[i] = getText(R.string.title_select_shortcut); } else { // we have an app! // now reconstruct the intent to launch it through the front // door ComponentName com = new ComponentName( bestMatch.activityInfo.applicationInfo.packageName, bestMatch.activityInfo.name); mHotseats[i] = new Intent(Intent.ACTION_MAIN).setComponent(com); // load the app label for accessibility mHotseatLabels[i] = bestMatch.activityInfo.loadLabel(pm); } } if (LOGD) { Log.d(TAG, "loadHotseats: hotseat " + i + " final intent=[" + ((mHotseats[i] == null) ? "null" : mHotseats[i].toUri(Intent.URI_INTENT_SCHEME)) + "] label=[" + mHotseatLabels[i] + "]" ); } } }
有点复杂,主要代码其实如下:
PackageManager pm = getPackageManager(); ResolveInfo bestMatch = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); List<ResolveInfo> allMatches = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);这样就获取了。下面以一个简单的例子结束, 获取在sd卡中安装的程序列表:
private void getSdcardApps(){ mSdcardAppsList.clear(); ActivityManager am = (ActivityManager)mLauncher.getSystemService(Activity.ACTIVITY_SERVICE); PackageManager pm =mLauncher.getPackageManager(); List<android.content.pm.ApplicationInfo> list = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES); for (android.content.pm.ApplicationInfo appInfo : list) { if((appInfo.flags & android.content.pm.ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0){ for (ApplicationInfo applicationInfo : mAllAppsList) { if(appInfo.packageName.equals(applicationInfo.componentName.getPackageName())){ mSdcardAppsList.add(applicationInfo); break; } } } } mAppsAdapter = new AppsAdapter(getContext(), mSdcardAppsList); mAppsAdapter.notifyDataSetChanged(); mGrid.setAdapter(mAppsAdapter); text.setVisibility(View.VISIBLE); text.setBackgroundResource(R.drawable.tab_mmenu_b3_normal); }
原文链接: http://blog.csdn.net/aomandeshangxiao/article/details/6951161