Android12 Launcher3客制化:添加非抽屉模式(可动态切换)、图标自动补位功能

本文详细介绍了如何在Android12的Launcher3中实现非抽屉模式和图标自动补位功能,包括记录当前模式、加载桌面图标、安装新应用处理、禁止移除桌面图标、上滑操作处理、数据库管理以及解决小部件消失和图标重复问题等关键步骤。
摘要由CSDN通过智能技术生成

目录

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<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()方法:

//把所有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);

        }

    }

网上的很多博客这个地方都有点不太一样,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<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 : 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);
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值