1、将竖屏加载(抽屉型加载)改成横屏加载,Launcher的oncreate方法和onresume里面会调用model.startLoader去加载数据,startLoader里面又会创建一个loaderTask的任务,这个任务执行加载工作空间loadWorkspace()、绑定工作空间bindWorkspace()、加载所有app loadAllApps()、绑定所有app bindAllApps()、更新图标缓存updateIconCache()、加载快捷方式loadDeepShortcuts()、绑定快捷方式bindDeepShortcuts()、加载小部件widgetsModel.update()、绑定小部件bindWidgets(),我在加载所有app这个步骤将原本的竖屏加载改成横屏加载,通过loadAllApps得到一个 LauncherActivityInfo的list,自己写了个方法verifyApplications()去解析这个List<LauncherActivityInfo>,具体的做法就是将List<LauncherActivityInfo>转成List<InstallShortcutReceiver.PendingInstallShortcutInfo>,然后通过InstallShortcutReceiver.PendingInstallShortcutInfo的getItemInfo方法获取到List<Pair<ItemInfo, Object>>,将这个List<Pair<ItemInfo, Object>>通过model. addAndBindAddedWorkspaceItems绑定到工作空间,将BaseModelUpdateTask的run()方法里面return语句屏蔽,保证每次都能执行execte加载桌面,在PackageUpdatedTask的execute方法addedOrModified.addAll(appsList.added);下面加了一个自己写的方法updateToWorkSpace(context, app, appsList);,这个跟在loadAllApps里面加的verifyApplications()做的是一样的事情,都是将list转化成可以添加到工作控件的类型,做完这些,竖屏加载桌面就变成横屏加载了。
private void verifyApplications(List<LauncherActivityInfo> apps) {
final Context context = mApp.getContext();
List<Pair<ItemInfo, Object>> installQueue = new ArrayList<>();
final List<UserHandle> profiles = mUserManager.getUserProfiles();
for (UserHandle user : profiles) {
ArrayList<InstallShortcutReceiver.PendingInstallShortcutInfo> added =
new ArrayList<InstallShortcutReceiver.PendingInstallShortcutInfo>();
synchronized (this) {
for (LauncherActivityInfo app : apps) {
InstallShortcutReceiver.PendingInstallShortcutInfo pendingInstallShortcutInfo =
new InstallShortcutReceiver.PendingInstallShortcutInfo(app, context);
added.add(pendingInstallShortcutInfo);
installQueue.add(pendingInstallShortcutInfo.getItemInfo());
}
}
if (!added.isEmpty()) {
mApp.getModel().addAndBindAddedWorkspaceItems(Provider.of(installQueue));
}
}
}
public void updateToWorkSpace(Context context, LauncherAppState app , AllAppsList appsList) {
List<Pair<ItemInfo, Object>> installQueue = new ArrayList<>();
final List<UserHandle> profiles = UserManagerCompat.getInstance(context).getUserProfiles();
ArrayList<InstallShortcutReceiver.PendingInstallShortcutInfo> added =
new ArrayList<InstallShortcutReceiver.PendingInstallShortcutInfo>();
for (UserHandle user : profiles) {
final List<LauncherActivityInfo> apps = LauncherAppsCompat.getInstance(context).getActivityList(null, user);
synchronized (this) {
for (LauncherActivityInfo info : apps) {
for (AppInfo appInfo : appsList.added) {
if (info.getComponentName().equals(appInfo.componentName)) {
InstallShortcutReceiver.PendingInstallShortcutInfo mPendingInstallShortcutInfo =
new InstallShortcutReceiver.PendingInstallShortcutInfo(info,context);
added.add(mPendingInstallShortcutInfo);
installQueue.add(mPendingInstallShortcutInfo.getItemInfo());
}
}
}
}
}
2、隐藏桌面的某个应用图标,比如要在桌面上隐藏QQ,在loadAllApps方法里先是对List<UserHandle>进行遍历,在遍历每个userhanle的List<LauncherActivityInfo>,我通过调试发现有的手机有3个userhandle,一般都是第一个userHandle的桌面图标是我们想要的,所以在遍历第一个userHandel的List<LauncherActivityInfo>时将要隐藏图标的应用剔除掉,通过读取LauncherActivityInfo.getApplicationInfo().packageName与目标包名进行匹配,一样就移除。
3、修改桌面几乘几的布局和hotseat快捷方式,因为有个需求是要所有机型都要显示4x4的桌面,先将device_profiles.xml中的profile配置删到只剩
<profile
launcher:name="Pixel (Display Size set to Largest)"
launcher:minWidthDps="296"
launcher:minHeightDps="496"
launcher:numRows="4"
launcher:numColumns="4"
launcher:numFolderRows="3"
launcher:numFolderColumns="4"
launcher:minAllAppsPredictionColumns="4"
launcher:numHotseatIcons="4"
launcher:goiconSize="56"
launcher:landscapeIconSize="54"
launcher:iconTextSize="13.0"
launcher:defaultLayoutId="@xml/default_workspace_4x4"
/>
然后在dw_hotseat_4.xml中将第三个图标的intent改成了自定义的一个intent例如:<favorite launcher:uri="intent:#Intent;component=包名/Activity名;B.isLauncher=true;end" />
4、修改桌面图标为自定义图标,在IconCache类里面有个cacheLocked方法,在return entry将entry.icon重新赋值,这样就能达到更换图标的效果了。
5、改桌面点击跳转,Launcher里面有个onClick(View v)方法,最终打开app的方法是startAppShortcutOrInfoActivity(),在这里通过ItemInfo的title进行目标匹配,匹配到的时候将通过item.getIntent()获取到的intent修改为自己要的intent就可以了。
6、改局部刷新,通过调用LauncherModel的onPackageChanged方法刷新指定包名app的状态。