自定義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);
        }
    }
複製代碼
相關文章
相關標籤/搜索