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();

}

}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐