1. 程式人生 > >水波紋進度條(自定義View——進階篇1)

水波紋進度條(自定義View——進階篇1)

自定義控制元件——ProgressCircleView(水波紋進度條)

最近在很多群都有提到水波紋進度條,看起來蠻唬人的,但是我們要相信毛爺爺的話,一切看起來唬人的都是紙老唬,一言不合,還是先貼效果圖:
這個效果該怎麼實現呢,今天還是講思路,思路從圖開始,接下來的這張圖是我嘔心瀝血之作,幫助大家分分鐘找到解決方案,所以再醜你們也不要嫌棄,上圖:
看到這裡,我也感覺畫風不對,不過重要的還是思想,以後會慢慢改進: 看到沒,就這麼簡單,水波紋部分不正是 貝塞爾曲線 左右下邊距 形成圖案的交集部分麼,搜噶斯內,到這裡所有的問題都已不是問題,當然可能很多人可能只聽過貝塞爾曲線,不過不了解到底是個啥玩意,感覺蠻叼的樣子,我來給大家稍稍介紹下:
這裡是二階貝塞爾曲線,多階就不介紹了,免得跑題了。
工具類,二階貝塞爾曲線繪製:path.rQuadTo(dx1, dy1, dx2, dy2);P0為起點座標,方法中的引數對應P1和P2的座標點。
方法介紹了,該是貼程式碼的時候了,為了方便大家理解,我這裡分別從左至右、從右至左繪製了貝塞爾曲線,不過視覺效果上似乎沒差別:
/**
     * @param direction 0從左至右,1從右至左(繪製)
     */
    private void drawQuad(int direction) {
        //繪製進度波紋
        path.reset();
        //計算畫筆所在的Y座標值,直徑 - 進度移動距離
        float py = (1 - (float) currentProgress / maxProgress) * 2 * radius;
        switch (direction) {
            case 0:
                //x軸不變,向Y軸方向移動畫筆(這裡為向上)
                path.moveTo(0, py);
                //預設水波紋半徑
                float pRadius = 2f * radius / progressDensity;//progressDensity為水波紋的密度
                //水波紋當前半徑
                float cRadius = (1 - (float) currentProgress / maxProgress) * pRadius;
                for (int i = 0; i < progressDensity; i++) {
                    //這裡是在一條直線上繪製的是上下迴圈的貝塞爾曲線
                    //下曲線,這裡可以去掉,但不去掉會更美觀
                    path.rQuadTo(pRadius, cRadius, 2 * pRadius, 0);//繪製貝塞爾曲線,每次繪製相對上一條的位置開始
                    //上曲線
                    path.rQuadTo(pRadius, -cRadius, 2 * pRadius, 0);
                }
                path.lineTo(width, py);
                path.lineTo(width, heigth);
                path.lineTo(0, heigth);
                break;
            case 1:
                //x軸不變,向Y軸方向移動畫筆(這裡為向上)
                path.moveTo(width, py);
                //預設水波紋半徑
                float pRadius1 = 2f * radius / progressDensity;//progressDensity為水波紋的密度
                //水波紋當前半徑
                float cRadius1 = (1 - (float) currentProgress / maxProgress) * pRadius1;
                for (int i = 0; i < progressDensity; i++) {
                    //這裡是在一條直線上繪製的是上下迴圈的貝塞爾曲線
                    //下曲線,這裡可以去掉,但不去掉會更美觀
                    path.rQuadTo(-pRadius1, cRadius1, -2 * pRadius1, 0);//繪製貝塞爾曲線,每次繪製相對上一條的位置開始
                    //上曲線
                    path.rQuadTo(-pRadius1, -cRadius1, -2 * pRadius1, 0);
                }
                path.lineTo(0, heigth);
                path.lineTo(width, heigth);
                path.lineTo(width, py);
                break;
            default:
                break;
        }
        path.close();
        bitmapCanvas.drawPath(path, progressPaint);
    }
說到了,就該結束了,如果你只想當搬運工,我也很善解人意的提供原始碼大笑