android launcher folder,Android8.1 Launcher3 修改文件夹样式(二)
Android8.1 Launcher3 修改文件夹样式(二)这篇博客修改的是文件夹的缩略图,修改为九宫格。原生的是一个圆形,而且最多只能显示四个app的缩略图,修改为国内常见的九宫格形式;上代码src/com/android/launcher3/folder/FolderIcon.java可以看到这个FolderIcon是一个view,那么基本就可以确定这就是文件夹的缩略图了,但是找了一下没发现
Android8.1 Launcher3 修改文件夹样式(二)
这篇博客修改的是文件夹的缩略图,修改为九宫格。
原生的是一个圆形,而且最多只能显示四个app的缩略图,修改为国内常见的九宫格形式;
上代码
src/com/android/launcher3/folder/FolderIcon.java
可以看到这个FolderIcon是一个view,那么基本就可以确定这就是文件夹的缩略图了,但是找了一下没发现它有onDraw()方法,也没有onLayout()方法;
找了一会没有思路,这个时候我转变了思路,在folder包下面,发现src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
这个类,有兴趣的同学可以看看,里面有三角函数,还有圆周率,因为原生的文件夹缩略图就是以圆形排列的,为了确定,修改这两个常量,就可以看出效果:/* 20180702 modify begin */// static final int MAX_NUM_ITEMS_IN_PREVIEW = 4;static final int MAX_NUM_ITEMS_IN_PREVIEW = Integer.MAX_VALUE;/* 20180702 modify end */private static final int MIN_NUM_ITEMS_IN_PREVIEW = 2;/* 20180702 modify begin */private static final float MIN_SCALE = 0.22f;/* 20180702 modify end */
到这里就可以确定文件夹缩略图的规则就是这个类做的了,那么我们就要修改一下这个规则:@Overridepublic PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
PreviewItemDrawingParams params) {
......
transX = mTmpPoint[0];
transY = mTmpPoint[1];/* 20180702 modify begin */int padl = 15;int padt = 15;int tempIndex = index % 9;
transX = padl + mIconSize * MIN_SCALE * getCol(tempIndex) + getCol(tempIndex) * 5;
transY = padt + mIconSize * MIN_SCALE * (getRow(tempIndex) - 1) + (getRow(tempIndex) - 1) * 5;/* 20180702 modify end */if (params == null) {params = new PreviewItemDrawingParams(transX, transY, totalScale, overlayAlpha);
} else {params.update(transX, transY, totalScale);params.overlayAlpha = overlayAlpha;
}return params;
}/* 20180702 modify begin */private int getRow(int index) {return index / 3 + 1;
}private int getCol(int index) {return (index) % 3;
}/* 20180702 modify end */
文件夹的显示规则修改了,那么它的图形是怎么绘制出来的呢,偶然间让我发现了一个dispatchDraw()方法,再看dispatchDraw()里面,恍然大悟
src/com/android/launcher3/folder/FolderIcon.java -> dispatchDraw():@Overrideprotected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);if (!mBackgroundIsVisible) return;
mPreviewItemManager.recomputePreviewDrawingParams();if (!mBackground.drawingDelegated()) {
mBackground.drawBackground(canvas);
}if (mFolder == null) return;if (mFolder.getItemCount() == 0 && !mAnimating) return;
final int saveCount;if (canvas.isHardwareAccelerated()) {
saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null,
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
} else {
saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);/* 20180702 modify begin */// if (mPreviewLayoutRule.clipToBackground()) {// canvas.clipPath(mBackground.getClipPath(), Region.Op.INTERSECT);// }/* 20180702 modify end */}
mPreviewItemManager.draw(canvas);/* 20180702 modify begin */// if (mPreviewLayoutRule.clipToBackground() && canvas.isHardwareAccelerated()) {// mBackground.clipCanvasHardware(canvas);// }/* 20180702 modify end */canvas.restoreToCount(saveCount);/* 20180702 modify begin */// if (mPreviewLayoutRule.clipToBackground() && !mBackground.drawingDelegated()) {// mBackground.drawBackgroundStroke(canvas);// }///* 20180702 modify end */drawBadge(canvas);
}
最后在修改一个缩略图背景,
src/com/android/launcher3/folder/PreviewBackground.java :public void drawBackground(Canvas canvas) {
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(getBgColor());
drawCircle(canvas, 0 /* deltaRadius */);/* 20180702 modify begin */// drawShadow(canvas);/* 20180702 modify end */}private void drawCircle(Canvas canvas,float deltaRadius) {float radius = getScaledRadius();/* 20180702 modify begin */// canvas.drawCircle(radius + getOffsetX(), radius + getOffsetY(),// radius - deltaRadius, mPaint);canvas.drawRoundRect(0 + getOffsetX(), 0 + getOffsetY(), radius * 2 + getOffsetX(),
radius * 2 + getOffsetY(), 30, 30, mPaint);/* 20180702 modify end */}
到这里,我们的文件夹缩略提就以九宫格展示了;
但是仍然遗留了问题,就是当我们的文件夹第一页满了的情况下,在文件夹外长按一个APP,文件夹的缩略图应该滑动到文件夹的当前页;
这个看了一会,找到了文件夹动画(打开文件夹,滑动到第二页,关闭文件夹后,缩略图的动画)的地方,但是没修改成功,现在附上代码,如果有同学弄好了,还请指教
src/com/android/launcher3/folder/PreviewItemManager.java:void onFolderClose(int currentPage) {// If we are not closing on the first page, we animate the current page preview items// out, and animate the first page preview items in.mShouldSlideInFirstPage = currentPage != 0;if (mShouldSlideInFirstPage) {
mCurrentPageItemsTransX = 0;
buildParamsForPage(currentPage, mCurrentPageParams, false);
onParamsChanged();
ValueAnimator slideAnimator = ValueAnimator.ofFloat(0, ITEM_SLIDE_IN_OUT_DISTANCE_PX);
slideAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {
mCurrentPageItemsTransX = (float) valueAnimator.getAnimatedValue();
onParamsChanged();
}
});
slideAnimator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {
mCurrentPageParams.clear();
}
});
slideAnimator.setStartDelay(SLIDE_IN_FIRST_PAGE_ANIMATION_DURATION_DELAY);
slideAnimator.setDuration(SLIDE_IN_FIRST_PAGE_ANIMATION_DURATION);
slideAnimator.start();
}
}
更多推荐
所有评论(0)