Android12 Launcher3客制化:添加非抽屉模式(可动态切换)、图标自动补位功能 | 您所在的位置:网站首页 › qq群名字动态图标代码不能用了 › Android12 Launcher3客制化:添加非抽屉模式(可动态切换)、图标自动补位功能 |
目录 1、声明标志字段用以记录当前模式 2、把所有图标加载到桌面上 3、安装新的app之后需要添加到桌面: 4、桌面模式不允许移除桌面图标: 5、自动补位处理: 6、上滑操作 7、数据库处理 8、抽屉模式切换 9、切换桌面布局和非桌面布局后,小部件消失问题 10、切换列数少的layout再切换回来,桌面图标与hotseat图标重复问题: 本文所有代码修改/添加在代码实例的注释begin add和end add之间 1、声明标志字段用以记录当前模式Launcher.java isDeskMode:是否桌面模式(非抽屉模式) isAutoFull:是否自动补位(只做当前是否自动补位开关的值,自动补位功能需要在桌面模式生效,所以声明为私有,然后提供对外方法需要判断同时是桌面模式): //begin add public static boolean isDeskMode = false; private static boolean isAutoFull = false; public static boolean isAutoFull(){ return isDeskMode && isAutoFull; } public static void isAutoFull(boolean autoFull){ isAutoFull = autoFull; } //end add 2、把所有图标加载到桌面上LoaderTask.java 在run方法里面,注释的第二步后面执行一下代码: // second step Trace.beginSection("LoadAllApps"); List allActivityList; try { allActivityList = loadAllApps(); LauncherAppMonitor.getInstance(mApp.getContext()).onLoadAllAppsEnd(new ArrayList(mBgAllAppsList.data)); } finally { Trace.endSection(); } logASplit(logger, "loadAllApps"); //begin add if(Launcher.isDeskMode){ verifyApplications(); } //end addverifyApplications()方法: //把所有App放到workspace里面 public void verifyApplications() { Context context = mApp.getContext(); ArrayList installQueue = new ArrayList(); UserManager mUserManager = context.getSystemService(UserManager.class); final List profiles = mUserManager.getUserProfiles(); ArrayList added = new ArrayList(); LauncherApps mLauncherApps = context.getSystemService(LauncherApps.class); for (UserHandle user : profiles) { final List apps = mLauncherApps.getActivityList(null, user); synchronized (this) { for (LauncherActivityInfo info : apps) { for (AppInfo appInfo : mBgAllAppsList.data) { String packageName = info.getComponentName().getPackageName(); if (info.getComponentName().equals(appInfo.componentName)) { ItemInstallQueue.PendingInstallShortcutInfo mPendingInstallShortcutInfo = new ItemInstallQueue.PendingInstallShortcutInfo(packageName,info.getUser()); added.add(mPendingInstallShortcutInfo); installQueue.add(mPendingInstallShortcutInfo.getItemInfo(context)); } } } } } if (!added.isEmpty()) { mApp.getModel().addAndBindAddedWorkspaceItems(installQueue); } }网上的很多博客这个地方都有点不太一样,PendingInstallShortcutInfo都是 InstallShortcutReceiver.PendingInstallShortcutInfo的,但是Android12的代码里面根本就没有InstallShortcutReceiver这个类了,所以全局搜索PendingInstallShortcutInfo发现ItemInstallQueue才有这个类,并且是私有的,我们需要把它改成public。然后网上 InstallShortcutReceiver.PendingInstallShortcutInfo的才是只需要传info和context,我们找到的ItemInstallQueue.PendingInstallShortcutInfo类并不是这样的才是,所以根据它需要的参数传递包名和user。 以上代码加载app不成功需要修改类:BaseModelUpdateTask.java 将原return添加一个判断,如果是桌面模式则继续执行,不要return。 @Override public final void run() { if (!mModel.isModelLoaded() && !mIgnoreLoaded) { if (DEBUG_TASKS) { Log.d(TAG, "Ignoring model task since loader is pending=" + this); } // Loader has not yet run. //begin add if(!Launcher.isDeskMode){ return; } //end add } execute(mApp, mDataModel, mAllAppsList); } 3、安装新的app之后需要添加到桌面:PackageUpdatedTask.java 修改方法execute: bindApplicationsIfNeeded(); //begin add if(Launcher.isDeskMode){ updateToWorkSpace(app, appsList); } //end add final IntSet removedShortcuts = new IntSet(); // Shortcuts to keep even if the corresponding app was removed final IntSet forceKeepShortcuts = new IntSet();updateToWorkSpace方法和加载所有app到桌面类似: //begin add public void updateToWorkSpace(LauncherAppState app, AllAppsList appsList) { Context context = app.getContext(); ArrayList installQueue = new ArrayList(); UserManager mUserManager = context.getSystemService(UserManager.class); final List profiles = mUserManager.getUserProfiles(); ArrayList added = new ArrayList(); LauncherApps mLauncherApps = context.getSystemService(LauncherApps.class); for (UserHandle user : profiles) { final List apps = mLauncherApps.getActivityList(null, user); synchronized (this) { for (LauncherActivityInfo info : apps) { for (AppInfo appInfo : appsList.data) { String packageName = info.getComponentName().getPackageName(); if (info.getComponentName().equals(appInfo.componentName)) { ItemInstallQueue.PendingInstallShortcutInfo mPendingInstallShortcutInfo = new ItemInstallQueue.PendingInstallShortcutInfo(packageName,info.getUser()); added.add(mPendingInstallShortcutInfo); installQueue.add(mPendingInstallShortcutInfo.getItemInfo(context)); } } } } } if (!added.isEmpty()) { app.getModel().addAndBindAddedWorkspaceItems(installQueue); } } //end add 4、桌面模式不允许移除桌面图标:DeleteDropTarget.java application类型的控件不允许拖动移除,小部件、快捷方式、文件夹等可以移除,这里可以根据需求添加或的判断。 protected boolean supportsDrop(ItemInfo info) { //begin add if(Launcher.isDeskMode && info.itemType == Favorites.ITEM_TYPE_APPLICATION){ return false; } //end add return true; }我这里需求是可以移除文件夹,移除了之后,需要把文件夹里面app重新加载回桌面,并且桌面模式下移除了不需要撤销操作: public void completeDrop(DragObject d) { ItemInfo item = d.dragInfo; if (canRemove(item)) { //begin add onAccessibilityDrop(null, item); |
CopyRight 2018-2019 实验室设备网 版权所有 |