On the home page, when we click the intermediate button, we will jump to one,
How is it implemented in the code? Let's look at it:
mHandleView = (HandleView) findViewById(R.id.all_apps_button); mHandleView.setLauncher(this); mHandleView.setOnClickListener(this); mHandleView.setOnLongClickListener(this);
Let's look at the onclick () method: In The onclick method, there is a code
else if (v == mHandleView) { if (isAllAppsVisible()) { closeAllApps(true); } else { showAllApps(true); }
Let's look at the showallapps () method.
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); }
Mall1_grid is used above. Let's look for this control:
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);
The above code is defined in the setupview () method in launcher. java.
All_apps_view is defined in all_app_2d.xml.
In allapp2d. Java, you can find the methods used by mallappsgrid, such as addapps, removeapps, and 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(); } } }
The zoom () method contains mgrid. setadapter (mappsadapter). In the constructor, assign a value to the adapter.
public AllApps2D(Context context, AttributeSet attrs) { super(context, attrs); setVisibility(View.GONE); setSoundEffectsEnabled(false); mAppsAdapter = new AppsAdapter(getContext(), mAllAppsList); mAppsAdapter.setNotifyOnChange(false); }
How does one obtain the Application List? Let's go back to launcher. Java, in 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] + "]" ); } } }
The main code is as follows:
PackageManager pm = getPackageManager();ResolveInfo bestMatch = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);List<ResolveInfo> allMatches = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
This will be obtained. The following is a simple example to get the list of programs installed on the SD card:
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);}