Android8.1 Launcher3 修改文件夹样式(二)

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 */

到这里就可以确定文件夹缩略图的规则就是这个类做的了,那么我们就要修改一下这个规则:

@Override
    public 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():

@Override
    protected 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() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    mCurrentPageItemsTransX = (float) valueAnimator.getAnimatedValue();
                    onParamsChanged();
                }
            });
            slideAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public 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();
        }
    }

你可能感兴趣的:(Android)