Android12 Launcher3 customization: add non-drawer mode (can be switched dynamically), icon auto-fill function

Table of contents

1. Declare the flag field to record the current mode

2. Load all icons to the desktop

3. After installing the new app, you need to add it to the desktop:

4. Desktop mode does not allow removal of desktop icons:

5. Automatic filling processing:

6. Swipe up operation

7. Database processing

8. Drawer mode switching

9. The problem of widgets disappearing after switching between desktop layout and non-desktop layout

10. When switching to a layout with a small number of columns and then switching back, the desktop icon and the hotseat icon are duplicated:


All code modifications/adds in this article are between the comments begin add and end add in the code examples.

1. Declare the flag field to record the current mode

Launcher.java

isDeskMode: whether desktop mode (not drawer mode)

isAutoFull: Whether to auto-fill (only the current value of the auto-fill switch is used. The auto-fill function needs to take effect in desktop mode, so it is declared as private, and then an external method is provided to determine whether it is also desktop mode):

//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. Load all icons to the desktop

LoaderTask.java

In the run method, execute the following code after the second step of the comment:

// second step

Trace.beginSection("LoadAllApps");

List<LauncherActivityInfo> 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 add

verifyApplications() method:

//把所有App放到workspace里面

    public void verifyApplications() {

        Context context = mApp.getContext();

        ArrayList<Pair<ItemInfo, Object>> installQueue = new ArrayList<>();

        UserManager mUserManager = context.getSystemService(UserManager.class);

        final List<UserHandle> profiles = mUserManager.getUserProfiles();

        ArrayList<ItemInstallQueue.PendingInstallShortcutInfo> added = new ArrayList<>();

        LauncherApps mLauncherApps = context.getSystemService(LauncherApps.class);

        for (UserHandle user : profiles) {

            final List<LauncherActivityInfo> 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);

        }

    }

Many blogs on the Internet are a little different in this place. PendingInstallShortcutInfo all belongs to InstallShortcutReceiver.PendingInstallShortcutInfo, but there is no class InstallShortcutReceiver in the Android12 code at all. So after searching globally for PendingInstallShortcutInfo, we found that ItemInstallQueue only has this class, and it is private. We It needs to be changed to public. Then the online InstallShortcutReceiver.PendingInstallShortcutInfo only needs to pass info and context. The ItemInstallQueue.PendingInstallShortcutInfo class we found is not like this, so the package name and user are passed according to the parameters it requires.

If the above code fails to load the app, you need to modify the class: BaseModelUpdateTask.java

Add a judgment to the original return. If it is desktop mode, continue execution without returning.

@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. After installing the new app, you need to add it to the desktop:

PackageUpdatedTask.java

Modify method executeÿ

Guess you like

Origin blog.csdn.net/qq_35584878/article/details/129991459