自定义View合辑(5)-仿QQ邮箱下拉刷新

为了增强对自定义 View 的认知以及开发能力,我计划这段时间陆续来完成几个难度从易到难的自定义 View,并简单的写几篇博客来进行介绍,全部的代码也都会开源,也但愿读者能给个 star 哈 GitHub 地址:github.com/leavesC/Cus… 也能够下载 Apk 来体验下:www.pgyer.com/CustomViewjava

先看下效果图:git

和 QQ邮箱 官方的仍是有点差异的,没完成仿形成功,不过大概思路明白了就能够的了~github

以左边的小圆做为例子,其变化规律是这样的canvas

  • 小圆半径从 0 逐渐增大到 minRadius ,此过程只是半径增大,其坐标点不变,依然处于最左边
  • 小圆从左边逐渐位移到中间位置,此过程半径逐渐从 minRadius 增大到 maxRadius,X 坐标逐渐增大,Y 坐标不变
  • 小圆从中间逐渐位移到最右边,此过程半径从 maxRadius 逐渐减少到 minRadius,X 坐标逐渐增大,Y 坐标不变
  • 小圆处于最右边保持坐标点不变,半径逐渐从 minRadius 减少到 0

三个小圆的变化规律都是如上所述,只是起始状态有所差异而已,能够规定各个状态占总的动画时间的四分之一,所以 CircleRefreshView 的重点就在于根据动画值的变化来计算三个小圆的坐标系以及半径大小ide

private void updateCircle(int index, float fraction) {
        // x x x
        // ------------||-------------||--------------||------------
        // 1/4 2/4 3/4
        // 1/4 2/4 3/4 4/4

        // 左边-绿色
        // 半径从0到min 半径从min到max 半径从max到min 半径从min到0

        // 中间-橙色
        // 半径从max到min 半径从min到0
        //半径从0到min 半径从min到max

        // 右边-红色
        // 半径从min到0
        //半径从0到min 半径从min到max 半径从max到min

        float radius = 0;
        float x = 0;
        switch (index) {
            case LEFT: {
                if (fraction <= 1f / 4f) {
                    radius = minRadius * (4f * fraction);
                    x = minRadius;
                } else if (fraction <= 0.5f) {
                    float percent = (fraction - 1f / 4f) * 4f;
                    radius = minRadius + percent * (maxRadius - minRadius);
                    x = minRadius + percent * (contentWidth / 2f - minRadius);
                } else if (fraction <= 3f / 4f) {
                    float percent = (fraction - 0.5f) * 4f;
                    radius = maxRadius - percent * (maxRadius - minRadius);
                    x = contentWidth / 2f + percent * (contentWidth / 2f - minRadius);
                } else {
                    radius = minRadius - (fraction - 3f / 4f) * 4f * minRadius;
                    x = contentWidth - minRadius;
                }
                break;
            }
            case CENTER: {
                if (fraction <= 1f / 4f) {
                    float percent = fraction * 4f;
                    radius = maxRadius - (maxRadius - minRadius) * percent;
                    x = contentWidth / 2f + (contentWidth / 2f - minRadius) * percent;
                } else if (fraction <= 0.5f) {
                    radius = minRadius - (fraction - 1f / 4f) * 4f * minRadius;
                    x = contentWidth - minRadius;
                } else if (fraction <= 3f / 4f) {
                    radius = minRadius * (4f * (fraction - 0.5f));
                    x = minRadius;
                } else {
                    float percent = (fraction - 3f / 4f) * 4f;
                    radius = minRadius + (maxRadius - minRadius) * percent;
                    x = minRadius + (contentWidth / 2f - minRadius) * percent;
                }
                break;
            }
            case RIGHT: {
                if (fraction <= 1f / 4f) {
                    radius = minRadius - 4f * fraction * minRadius;
                    x = contentWidth - minRadius;
                } else if (fraction <= 0.5f) {
                    radius = minRadius * (4f * (fraction - 1f / 4f));
                    x = minRadius;
                } else if (fraction <= 3f / 4f) {
                    float percent = (fraction - 0.5f) * 4f;
                    radius = minRadius + (maxRadius - minRadius) * percent;
                    x = minRadius + (contentWidth / 2f - minRadius) * percent;
                } else {
                    float percent = (fraction - 3f / 4f) * 4f;
                    radius = maxRadius - (maxRadius - minRadius) * percent;
                    x = contentWidth / 2f + (contentWidth / 2f - minRadius) * percent;
                }
                break;
            }
        }
        Circle circle = circleList.get(index);
        circle.radius = radius;
        circle.x = x;
    }
复制代码

而后在 onDraw 方法里直接绘制三个小圆点便可动画

@Override
    protected void onDraw(Canvas canvas) {
        for (Circle circle : circleList) {
            paint.setColor(circle.color);
            canvas.drawCircle(circle.x + getPaddingLeft(), circle.y + getPaddingTop(), circle.radius, paint);
        }
    }
复制代码
相关文章
相关标签/搜索