溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android怎么自定義View實現(xiàn)橫向的雙水波紋進(jìn)度條

發(fā)布時間:2021-11-02 15:42:06 來源:億速云 閱讀:311 作者:小新 欄目:開發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)Android怎么自定義View實現(xiàn)橫向的雙水波紋進(jìn)度條,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

    思路分析

    整體效果可分為三個,繪制圓角背景和圓角矩形,繪制第一條和第二條水波浪,根據(jù)自定義進(jìn)度變化效果。

    功能實現(xiàn)

    1.繪制圓角背景和圓角矩形邊框

    圓角矩形邊框:

    private RectF rectBorder;
    if (rectBorder == null) {
        rectBorder = new RectF(0.5f * dp1, 0.5f * dp1, waveActualSizeWidth - 0.5f * dp1, waveActualSizeHeight - 0.5f * dp1);
    }
    canvas.drawRoundRect(rectBorder, dp27, dp27, borderPaint);

    我們創(chuàng)建一個新的畫布,然后在畫布里畫上圓角矩形背景和第一條和第二條水波浪:

    //這里用到了緩存 根據(jù)參數(shù)創(chuàng)建新位圖
    if (circleBitmap == null) {
        circleBitmap = Bitmap.createBitmap(waveActualSizeWidth, waveActualSizeHeight, Bitmap.Config.ARGB_8888);
    }
    //以該bitmap為底創(chuàng)建一塊畫布
    if (bitmapCanvas == null) {
        bitmapCanvas = new Canvas(circleBitmap);
    }
    // 圓角矩形背景,為了能讓波浪填充完整個圓形背景
    if (rectBg == null) {
        rectBg = new RectF(0, 0, waveActualSizeWidth, waveActualSizeHeight);
    }
    bitmapCanvas.drawRoundRect(rectBg, dp27, dp27, backgroundPaint);
    //裁剪圖片
    canvas.drawBitmap(circleBitmap, 0, 0, null);

    2.通過貝塞爾曲線實現(xiàn)雙水波

    1)實現(xiàn)第一條水波

    /**
     * 繪制波浪線
     */
    private Path canvasWavePath() {
        //要先清掉路線
        wavePath.reset();
        //起始點移至(0,0) p0 -p1 的高度隨著進(jìn)度的變化而變化
        wavePath.moveTo((currentPercent) * waveActualSizeWidth, -moveDistance);
        //最多能繪制多少個波浪
        //其實也可以用 i < getWidth() ;i+=waveLength來判斷 這個沒那么完美
        //繪制p0 - p1 繪制波浪線 這里有一段是超出View的,在View右邊距的右邊 所以是* 2
        for (int i = 0; i < waveNumber * 2; i++) {
            wavePath.rQuadTo(waveHeight, waveLength / 2, 0, waveLength);
            wavePath.rQuadTo(-waveHeight, waveLength / 2, 0, waveLength);
        }
        //連接p1 - p2
        wavePath.lineTo(0, waveActualSizeHeight);
        //連接p2 - p0
        wavePath.lineTo(0, 0);
        //封閉起來填充
        wavePath.close();
        return wavePath;
    }

    moveDistance為水波垂直方向移動的距離。

    waveLength為水波長度,一個上弧加一個下弧為一個波長。

    path的起始點為(0,0)可根據(jù)進(jìn)度動態(tài)改變,然后循環(huán)畫曲線,長度是有幾個波浪就是多長,然后連接到view高度的位置,最后到(0,0),形成一個封閉的區(qū)域,這樣就實現(xiàn)了一個填充的水波效果。

    2)繪制第二條水波,第二條水波和第一條類似,只是起始點變了:

    /**
     * 繪制第二層波浪
     */
    private Path canvasSecondPath() {
        secondWavePath.reset();
        //初始點移動到下方
        secondWavePath.moveTo((currentPercent) * waveActualSizeWidth, waveActualSizeHeight + moveDistance);
        for (int i = 0; i < waveNumber * 2; i++) {
            secondWavePath.rQuadTo(waveHeight, -waveLength / 2, 0, -waveLength);
            secondWavePath.rQuadTo(-waveHeight, -waveLength / 2, 0, -waveLength);
        }
        secondWavePath.lineTo(0, 0);
        secondWavePath.lineTo(0, waveActualSizeHeight);
        secondWavePath.close();
        return secondWavePath;
    }

    3.設(shè)置動畫使進(jìn)度和水波紋變化

    /**
     * 設(shè)置進(jìn)度
     *
     * @param currentProgress 進(jìn)度
     * @param duration        達(dá)到進(jìn)度需要的時間
     */
    public void setProgress(int currentProgress, long duration, AnimatorListenerAdapter listenerAdapter) {
        float percent = currentProgress * 1f / maxProgress;
        this.currentProgress = currentProgress;
        //從0開始變化
        currentPercent = 0;
        moveDistance = 0;
        mProgressAnimator = ValueAnimator.ofFloat(0, percent);
        //設(shè)置動畫時間
        mProgressAnimator.setDuration(duration);
        //讓動畫勻速播放,避免出現(xiàn)波浪平移停頓的現(xiàn)象
        mProgressAnimator.setInterpolator(new LinearInterpolator());
        mProgressAnimator.addUpdateListener(listener);
        mProgressAnimator.addListener(listenerAdapter);
        mProgressAnimator.start();
    
        // 波浪線
        startWaveAnimal();
    }
    
    /**
     * 波浪動畫
     */
    private void startWaveAnimal() {
        //動畫實例化
        if (waveProgressAnimator == null) {
            waveProgressAnimator = new WaveProgressAnimal();
            //設(shè)置動畫時間
            waveProgressAnimator.setDuration(2000);
            //設(shè)置循環(huán)播放
            waveProgressAnimator.setRepeatCount(Animation.INFINITE);
            //讓動畫勻速播放,避免出現(xiàn)波浪平移停頓的現(xiàn)象
            waveProgressAnimator.setInterpolator(new LinearInterpolator());
            //當(dāng)前視圖開啟動畫
            this.startAnimation(waveProgressAnimator);
        }
    }

    其中波浪動畫是通過改變moveDistance的值改變縱坐標(biāo)達(dá)到,進(jìn)度主要是通過改變百分比currentPercent改變波浪的橫坐標(biāo)達(dá)到。

    關(guān)于“Android怎么自定義View實現(xiàn)橫向的雙水波紋進(jìn)度條”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI