作者 Yuewei.wang
在使用手机的过程中,可能有这样的使用习惯,Launcher(即桌面)每一屏幕没有排列满app。这种情况下,如果下载新的应用并安装,新应用是安装到包含空位的最前面一屏如第一屏,这时你可能不想将其置于第一屏,但是拖动此应用到其他屏幕后,会导致第一屏排列发生变化,用户就需要重新排列。或者懒于拖动,但是造成分类较乱。那么我们是不是希望新安装的应用排在最后一屏,然后由我们自己放置。下面的修改就实现了此功能。
说明:本次修改基于android M MTK原生launcher应用 。
我们首先看一下新应用安装后在Launcher显示出来的流程。
接下来是详细处理流程:
public void processPackageAdd(String[] packages) {
mHomescreenApps = new ArrayList<>();
mWorkFolderApps = new ArrayList<>();
HashSet<String> packageSet = new HashSet<>();
final boolean userAppsExisted = getUserApps(packageSet);
boolean newPackageAdded = false;
long installTime = System.currentTimeMillis();
LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mContext);
for (String packageName : packages) {
if (!packageSet.contains(packageName)) {
packageSet.add(packageName);
newPackageAdded = true;
List<LauncherActivityInfoCompat> activities =
launcherApps.getActivityList(packageName, mUser);
if (!activities.isEmpty()) {
markForAddition(activities.get(0),installTime);
}
}
}
if (newPackageAdded) {
mPrefs.edit().putStringSet(mPackageSetKey, packageSet).apply();
finalizeAdditions(userAppsExisted);
}
}
获取当前用户的所有package,查看此package是否包含在其中,如果没有,则标记这是一个新增package。然后将此package加入到集合中,并进一步处理新增app。
private void finalizeAdditions(boolean addHomeScreenShortcuts) {
finalizeWorkFolder();
if (addHomeScreenShortcuts && !mHomescreenApps.isEmpty()) {
mModel.addAndBindAddedWorkspaceItems(mContext, mHomescreenApps);
}
}
是否符合添加到文件夹并标记,然后调用LauncherModel来绑定app Icon到workspace。
addAndBindAddedWorkspaceItems中的关键部分如下:
coords = findSpaceForItem(context,workspaceScreens, addedWorkspaceScreensFinal, 1, 1);
addItemToDatabase(context,itemInfo,
LauncherSettings.Favorites.CONTAINER_DESKTOP,
screenId,cordinates[0], cordinates[1]);
callbacks.bindAppsAdded(addedWorkspaceScreensFinal,
addNotAnimated, addAnimated, null);
实现了查找空位,并将此app的信息保存到数据库,然后调用Launcher将icon显示在屏幕上。可见,icon放置位置在findSpaceForItem中实现的。查找方式
intscreenCount = workspaceScreens.size();
intpreferredScreenIndex = workspaceScreens.isEmpty() ? 0 : 1;
if(preferredScreenIndex < screenCount) {
screenId =workspaceScreens.get(preferredScreenIndex);
found = findNextAvailableIconSpaceInScreen(
screenItems.get(screenId),cordinates, spanX, spanY);
}
从代码中可以看出是从第一屏开始寻找空位的。
那我们从最后一屏寻找空位就可以实现功能了。
int screenCount= workspaceScreens.size();
intlastScreenIndex = screenCount-1;
screenId= workspaceScreens.get(lastScreenIndex);
found= findNextAvailableIconSpaceInScreen(
screenItems.get(screenId),cordinates, spanX, spanY);