Launcher 安装APK快捷方式出现在末尾空白位置

在完成仿小米桌面的开发后,新的需求是安装APK时,快捷图标需自动出现在Launcher的末尾空白位置。通过查看Launcher3的源代码,发现在`LauncherModel.java`的`findNextAvailableIconSpace`方法中,可以找到屏幕的空白位置。接着,使用`findNextAvailableIconSpaceInScreen`方法确定快捷方式的具体坐标。原生代码采用从上到下,从左到右的顺序查找并插入空白位置。在`CellLayout.java`中,该过程被进一步处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在做完仿小米桌面之后,客户又提了一个新需求,要求安装APK的时候,快捷方式要出现在末尾空白位置 仿小米桌面方法请点击:Launcher3仿小米桌面

在代码中开始搜索之旅 在这个位置packages\apps\Launcher3\src\com\android\launcher3\LauncherModel.java

发现了一个findNextAvailableIconSpace方法

  // Try adding to the workspace screens incrementally, starting at the default or center
            // screen and alternating between +1, -1, +2, -2, etc. (using ~ ceil(i/2f)*(-1)^(i-1))
            firstScreenIndex = Math.max(firstScreenIndex, workspaceScreens.size()); //czy min
            int count = workspaceScreens.size();
            for (int screen = firstScreenIndex - 1; screen < count && !found; screen++) { //czy 加-1
                int[] tmpCoordinates = new int[2];
                if (findNextAvailableIconSpaceInScreen(items, tmpCoordinates,
                        workspaceScreens.get(screen))) {
                    // Update the Launcher db
                    return new Pair<Long, int[]>(workspaceScreens.get(screen), tmpCoordinates);
                }
            }
        }
        return null;
    }

这里说明先for (int screen = firstScreenIndex - 1; screen < count && !found; screen++)在找第几屏,如果没有就新建一个 具体增加快捷方式坐标得方法在这里
findNextAvailableIconSpaceInScreen(items, tmpCoordinates,workspaceScreens.get(screen)
tmpCoordinates这个参数就是快捷方式插入的位置
源代码原有的方法是从上到下 从左到右的顺序去遍历每一个位置 遇到空位就插进去 具体方法如下

static boolean findNextAvailableIconSpaceInScreen(ArrayList<ItemInfo> items, int[] xy,
                                 long screen) {
        int a = 0;
        int b = 0;
        LauncherAppState app = LauncherAppState.getInstance();
        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
        final int xCount = (int) grid.numColumns;
        final int yCount = (int) grid.numRows;
        boolean[][] occupied = new boolean[xCount][yCount];
        //czy
        ArrayList<Integer> myX = new ArrayList<Integer>();
        ArrayList<Integer> myY = new ArrayList<Integer>();
        //end

        int cellX, cellY, spanX, spanY;
        for (int i = 0; i < items.size(); ++i) {
            final ItemInfo item = items.get(i);
            if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
                if (item.screenId == screen) {
                    cellX = item.cellX;
                    cellY = item.cellY;
                    spanX = item.spanX;
                    spanY = item.spanY;
                    for (int x = cellX; 0 <= x && x < cellX + spanX && x < xCount; x++) {
                        for (int y = cellY; 0 <= y && y < cellY + spanY && y < yCount; y++) {
                            occupied[x][y] = true;
                        }
                    }

                    //czy
                    for (int y = 0; y < yCount; y++) {
                        for (int x = 0; x < xCount; x++) {
                            if(occupied[x][y]){
                                 myX.add(x);
                                 myY.add(y);
                            }
                        }
                    }
                    //end
                }
            }
        }

        return CellLayout.findVacantCellCzy(xy, 1, 1, xCount, yCount, occupied, myX, myY);//czy
    }

可以看到 返回的又是一个方法加参数 这个方法是重写的,直接给出路径和具体代码
路径packages\apps\Launcher3\src\com\android\launcher3\CellLayout.java

static boolean findVacantCellCzy(int[] vacant, int spanX, int spanY,
            int xCount, int yCount, boolean[][] occupied, ArrayList<Integer> myX, ArrayList<Integer> myY) {
        ArrayList<Integer> myXX = new ArrayList<Integer>();
        int xC = 0;
        int yC = 0;
        if(myX.size() >=1 && myY.size()>=1){
            xC = myX.get(myX.size()-1);
            yC = myY.get(myY.size()-1);
        }            
        for (int y = yC; y < yCount; y++) {
            for (int x = xC; x < xCount; x++) {
                boolean available = !occupied[x][y];
out:            for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
                    for (int j = y; j < y + spanY - 1 && y < yCount; j++) {
                        available = available && !occupied[i][j];
                        if (!available) break out;
                    }
                }

                if (available) {
                    if(x == 3 /*&& occupied[x][y - 1]*/){
                        for(int z = 0; z < xCount; z++){
                            if(!occupied[z][y]){                            
                                myXX.add(z);                            
                            }
                        }
                        if(myXX.size() == 4){
                            x = myXX.get(0);
                        }else{
                            if(myXX.size() != 0){
                                x = myXX.get(myXX.size() - 1);
                            }
                        }

                        Log.i("czy","-----x------"+x);
                    }
                    vacant[0] = x;
                    vacant[1] = y;
                    return true;
                }
            }
        }

        return false;
    }
    //end

最后把原生代码也贴出来,更直观

 static boolean findVacantCell(int[] vacant, int spanX, int spanY,
            int xCount, int yCount, boolean[][] occupied) {

        for (int y = 0; y < yCount; y++) {
            for (int x = 0; x < xCount; x++) {
                boolean available = !occupied[x][y];
out:            for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
                    for (int j = y; j < y + spanY - 1 && y < yCount; j++) {
                        available = available && !occupied[i][j];
                        if (!available) break out;
                    }
                }

                if (available) {
                    vacant[0] = x;
                    vacant[1] = y;
                    return true;
                }
            }
        }

        return false;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值