需求:文件夹样式按照下面的

android11桌面 安卓11桌面布局_android

猛的一看google源码的效果,和这个一模一样,但是当你把文件夹的个数换成两个,三个的时候就看到问题了

android11桌面 安卓11桌面布局_9宫格_02

    ..............  

android11桌面 安卓11桌面布局_边距_03

看到了吧。唉唉唉,你等会儿,最后一张是什么鬼,怎么看都像是个风车啊?!对,你没看错,就是google原生的文件夹就是圆形排列的,当你把ClippedFolderIconLayoutRule.java,文件中的  MAX_NUM_ITEMS_IN_PREVIEW  的值设置的无限大,就成了魔性的圆形分布了。那么怎样实现标准的效果呢?

分析:

怎样可以保证预览均匀分布,少于预览总数的时候,还是按照标准的顺序排列呢?大概跟把大象装冰箱的步骤差不多吧,^_^

  1. 首先你要显示多少个图标
  2. 为了适配各种分辨率的,我们可以反过来,只限制边距,间隙的大小,图标的大小在剩下的空间平分
  3. 计算出每个图标在文件夹的位置

接下来就一步一步来,首先先把需要的文件列出来,如下

alps\packages\apps\Launcher3\src\com\android\launcher3\folder\ClippedFolderIconLayoutRule.java

alps\packages\apps\Launcher3\src\com\android\launcher3\folder\FolderGridOrganizer.java

1.你想显示多少个图标就修改  ClippedFolderIconLayoutRule 的 MAX_NUM_ITEMS_IN_PREVIEW 这个值这个很简单没什么说的,默认是4,一般还会有9,其他的没见过

2.控制边距,比如你想设置边距为8,显示4个图标 ,那么你的图标大小是多少呢?不难分析,就是 图标大小 =(文件夹宽 - 3 * 8 ) / 2  ; 3表示左右边距 和 中间间隙 ; 2表示,一共四个则一行2个

3.有了上面的条件,确定每个图标的位置应该不难了吧

第一个图标需要从文件夹边缘移动的距离  X = (图标大小 + 间隙/2)* 0 + 左边距 ; Y = (图标大小 + 间隙/2)* 0 + 上边距

第二个图标需要从文件夹边缘移动的距离  X = (图标大小 + 间隙/2)* 1 + 左边距 ; Y = (图标大小 + 间隙/2)* 0 + 上边距

第三个图标需要从文件夹边缘移动的距离  X = (图标大小 + 间隙/2)* 0 + 左边距 ; Y = (图标大小 + 间隙/2)* 1 + 上边距

第四个图标需要从文件夹边缘移动的距离  X = (图标大小 + 间隙/2)* 1 + 左边距 ; Y = (图标大小 + 间隙/2)* 1 + 上边距

找到规律了没?图标的index是从0开始的,也就是说是 0 ,1 ,2 , 3,那个刚好就是 X = (图标大小 + 间隙/2)* (index % 每行个数); Y = (图标大小 + 间隙/2)* (index / 每列个数),这里面矩阵行列是相同的,都MAX_NUM_ITEMS_IN_PREVIEW  的平方根sqrt,最后得到 X = (图标大小 + 间隙/2)* (index % sqrt); Y = (图标大小 + 间隙/2)* (index / sqrt)

分析到此就完了,看看代码吧

//alps\packages\apps\Launcher3\src\com\android\launcher3\folder\FolderGridOrganizer.java
//只要小于最大预览数的都判断在preview中
public boolean isItemInPreview(int page, int rank) {
        // Modify by HZH on 2020/11/13 start
        // First page items are laid out such that the first 4 items are always in the upper
        // left quadrant. For all other pages, we need to check the row and col.
        /*if (page > 0 || mDisplayingUpperLeftQuadrant) {
            int col = rank % mCountX;
            int row = rank / mCountX;
            return col < 2 && row < 2;
        }*/
        // Modify by HZH on 2020/11/13 end
        return rank < MAX_NUM_ITEMS_IN_PREVIEW;
    }
//alps\packages\apps\Launcher3\src\com\android\launcher3\folder\ClippedFolderIconLayoutRule.java

public static final int MAX_NUM_ITEMS_IN_PREVIEW = 4;

public PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
            PreviewItemDrawingParams params) {
        totalScale = scaleForItem(curNumItems);
        float transX;
        float transY;
        float overlayAlpha = 0;

        // Modify by HZH on 2020/11/13  start
        getPosition(index, mTmpPoint);
        /*if (index == EXIT_INDEX) {
            // 0 1 * <-- Exit position (row 0, col 2)
            // 2 3
            getGridPosition(0, 2, mTmpPoint);
        } else if (index == ENTER_INDEX) {
            // 0 1
            // 2 3 * <-- Enter position (row 1, col 2)
            getGridPosition(1, 2, mTmpPoint);
        } else if (index >= MAX_NUM_ITEMS_IN_PREVIEW) {
            // Items beyond those displayed in the preview are animated to the center
            mTmpPoint[0] = mTmpPoint[1] = mAvailableSpace / 2 - (mIconSize * totalScale) / 2;
        } else {
            getPosition(index, curNumItems, mTmpPoint);
        }*/
        // Modify by HZH on 2020/11/13 end

        transX = mTmpPoint[0];
        transY = mTmpPoint[1];

        if (params == null) {
            params = new PreviewItemDrawingParams(transX, transY, totalScale, overlayAlpha);
        } else {
            params.update(transX, transY, totalScale);
            params.overlayAlpha = overlayAlpha;
        }
        return params;
    }

    // Add by HZH on 2020/11/13  start
    private void getPosition(int index, float[] result) {
        int sqrt = (int) Math.sqrt(MAX_NUM_ITEMS_IN_PREVIEW);
        int x = index % sqrt;
        int y = index / sqrt;
        float padding = 8;
        float iconSize = (mAvailableSpace - (sqrt + 1) * padding) / sqrt;
        // 这个totalScale注意去掉finial,生成成员变量
        totalScale = iconSize / mIconSize;
        result[0] = (iconSize + padding / 2) * x + padding;
        result[1] = (iconSize + padding / 2) * y + padding;
    }
    // Add by HZH on 2020/11/13  end

效果就是最顶部,第一个图的效果啦!如果有问题,你可再继续优化,这只是我的浅见。如果有幸帮到你,甚是荣幸!