【Launcher3】解决谷歌桌面的小部件重启后消失问题

1-问题摘要

这次主要解决困扰了我很久的时钟消失问题,大概是去年10月刚开始做EDLA项目的时候,需要定制谷歌桌面,桌面布局大概要改成这样:
在这里插入图片描述
时间显示在谷歌搜索框的上方,而安卓原生桌面大概是这样子的
在这里插入图片描述
我们开发一开始是使用小部件的方式加载谷歌时钟显示在桌面,而我们知道,桌面显示的任何组件都是以行和列的形式存在的,当时我们想要改时间为2行3列才能达到预期效果,但是奇怪的是2行3列的时间小部件在开机后并没有显示出来,暂时找不到原因只好使用1行3列布局,大概长这样
在这里插入图片描述

无论是默认定义2行或者是手动调整到2行,重启后时钟都会消失.

二-解决方法

先贴解决方法吧,原因分析写在后面,想看就看
小部件消失一般是跟谷歌搜索框有关,修改路径为Launcher3目录下的src/com/android/launcher3/model/LoaderCursor.java
找到这个方法

    /**
     * check & update map of what's occupied; used to discard overlapping/invalid items
     */
    protected boolean checkItemPlacement(ItemInfo item) {
        int containerIndex = item.screenId;
        if (item.container == Favorites.CONTAINER_HOTSEAT) {
            final GridOccupancy hotseatOccupancy =
                    mOccupied.get(Favorites.CONTAINER_HOTSEAT);

            if (item.screenId >= mIDP.numDatabaseHotseatIcons) {
                Log.e(TAG, "Error loading shortcut " + item
                        + " into hotseat position " + item.screenId
                        + ", position out of bounds: (0 to " + (mIDP.numDatabaseHotseatIcons - 1)
                        + ")");
                return false;
            }

            if (hotseatOccupancy != null) {
                if (hotseatOccupancy.cells[(int) item.screenId][0]) {
                    Log.e(TAG, "Error loading shortcut into hotseat " + item
                            + " into position (" + item.screenId + ":" + item.cellX + ","
                            + item.cellY + ") already occupied");
                    return false;
                } else {
                    hotseatOccupancy.cells[item.screenId][0] = true;
                    return true;
                }
            } else {
                final GridOccupancy occupancy = new GridOccupancy(mIDP.numDatabaseHotseatIcons, 1);
                occupancy.cells[item.screenId][0] = true;
                mOccupied.put(Favorites.CONTAINER_HOTSEAT, occupancy);
                return true;
            }
        } else if (item.container != Favorites.CONTAINER_DESKTOP) {
            // Skip further checking if it is not the hotseat or workspace container
            return true;
        }

        final int countX = mIDP.numColumns;
        final int countY = mIDP.numRows;
        if (item.container == Favorites.CONTAINER_DESKTOP && item.cellX < 0 || item.cellY < 0
                || item.cellX + item.spanX > countX || item.cellY + item.spanY > countY) {
            Log.e(TAG, "Error loading shortcut " + item
                    + " into cell (" + containerIndex + "-" + item.screenId + ":"
                    + item.cellX + "," + item.cellY
                    + ") out of screen bounds ( " + countX + "x" + countY + ")");
            return false;
        }

        if (!mOccupied.containsKey(item.screenId)) {
            GridOccupancy screen = new GridOccupancy(countX + 1, countY + 1);
            if (item.screenId == Workspace.FIRST_SCREEN_ID && FeatureFlags.QSB_ON_FIRST_SCREEN) {
                // Mark the first X columns (X is width of the search container) in the first row as
                // occupied (if the feature is enabled) in order to account for the search
                // container.
                int spanX = mIDP.numSearchContainerColumns;
                int spanY = 1;

                
                screen.markCells(0, 0, spanX, spanY, true);

            }
            mOccupied.put(item.screenId, screen);
        }
        final GridOccupancy occupancy = mOccupied.get(item.screenId);

        // Check if any workspace icons overlap with each other
        if (occupancy.isRegionVacant(item.cellX, item.cellY, item.spanX, item.spanY)) {
            occupancy.markCells(item, true);
            return true;
        } else {
            Log.e(TAG, "Error loading shortcut " + item
                    + " into cell (" + containerIndex + "-" + item.screenId + ":"
                    + item.cellX + "," + item.cellX + "," + item.spanX + "," + item.spanY
                    + ") already occupied");
            return false;
        }
    }

这个方法用来判断加载的组件相互之间是否存在布局重叠,如果有布局重叠,则不加载相应的组件
在这里插入图片描述
这行代码标记了谷歌搜索框的位置,从第1行第一列开始,占据spanX列和spanY行的空间,一般spanX在配置文件里定义为5,spanY为1,所以桌面的第一行基本是谷歌搜索框的天下,解决办法要根据你主布局是否需要搜索框来改:
1.如果你的布局不需要谷歌搜索框,就直接把screen.markCells(0, 0, spanX, spanY, true);给注释掉;
2.需要谷歌搜索框的话,就需要保持你桌面搜索框显示的位置和这里一致,查看src/com/android/launcher3/Workspace.java的bindAndInitFirstWorkspaceScreen()方法,里面定义了谷歌搜索框的位置
在这里插入图片描述
比如我这里定义居中的是从第二行第一列开始,占据5列1行空间,所以要把screen.markCells(0, 0, spanX, spanY, true);改为
screen.markCells(1, 2, 5, 1, true);

这样改了之后就不会计算出组件布局重叠区域了,可以正常显示衍生到桌面第一行的小部件,不单单是时钟组件.

三-原理分析

首先分析桌面启动加载小部件流程…未完待续

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Launcher3双层桌面指的是一种具有两个不同层级的桌面界面。这种设计可以提供更加灵活和个性化的桌面体验。 在Launcher3双层桌面中,通常会有两个主要的层级:上层桌面和下层桌面。上层桌面是我们平时使用的桌面界面,用于显示应用程序图标、小部件和壁纸等。用户可以在上层桌面上自定义排列应用程序图标、添加小部件以及更换壁纸等操作,以满足个性化需求。上层桌面可以通过滑动手势或者点击特定区域的按钮来访问下层桌面。 下层桌面通常用于展示更加高级和复杂的功能。它可以作为一个扩展或者补充上层桌面的功能工具。例如,用户可以将常用的设置、应用程序文件夹、搜索功能等放置在下层桌面上,以便于快速访问和使用。下层桌面还可以集成其他功用模块,如日历、天气等,帮助用户更加方便地获取信息。 通过使用Launcher3双层桌面,用户可以根据自己的喜好和需求对桌面界面进行个性化定制。无论是通过上层桌面上的排列图标还是下层桌面上的特殊功能,都能够使用户体验更加流畅和高效。双层桌面的设计还可以使用户更加方便地管理和组织应用程序和其他工具,提升整体的工作和娱乐效率。 总的来说,Launcher3双层桌面是一种拥有两个层级的桌面界面设计,可以提供更加灵活、个性化的桌面体验。通过上层桌面和下层桌面的结合,用户可以方便地管理应用程序、访问常用功能和获取相关信息,提升使用效率和满足个性化需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值