需求:文件夹样式按照下面的
猛的一看google源码的效果,和这个一模一样,但是当你把文件夹的个数换成两个,三个的时候就看到问题了
..............
看到了吧。唉唉唉,你等会儿,最后一张是什么鬼,怎么看都像是个风车啊?!对,你没看错,就是google原生的文件夹就是圆形排列的,当你把ClippedFolderIconLayoutRule.java,文件中的 MAX_NUM_ITEMS_IN_PREVIEW 的值设置的无限大,就成了魔性的圆形分布了。那么怎样实现标准的效果呢?
分析:
怎样可以保证预览均匀分布,少于预览总数的时候,还是按照标准的顺序排列呢?大概跟把大象装冰箱的步骤差不多吧,^_^
- 首先你要显示多少个图标
- 为了适配各种分辨率的,我们可以反过来,只限制边距,间隙的大小,图标的大小在剩下的空间平分
- 计算出每个图标在文件夹的位置
接下来就一步一步来,首先先把需要的文件列出来,如下
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
效果就是最顶部,第一个图的效果啦!如果有问题,你可再继续优化,这只是我的浅见。如果有幸帮到你,甚是荣幸!