成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

從無到有打造一個炫酷的進度條效果

pekonchan / 1047人閱讀

摘要:今天這篇文章要介紹的是一個酷炫的進度條的設(shè)計和實現(xiàn),在進度的文字內(nèi)容顏色以及切換的圖片等都可以自由設(shè)置。那么下面我們就開始從無到有實現(xiàn)一下這個酷炫的進度效果吧。三利用與來實現(xiàn)進度效果。四利用阻尼動畫實現(xiàn)進度條回彈效果。

今天這篇文章要介紹的是一個酷炫的進度條的設(shè)計和實現(xiàn),在進度的文字內(nèi)容、顏色以及切換的圖片等都可以自由設(shè)置。我們先看下效果 (創(chuàng)意受Dribbble的啟發(fā)):

整體效果還是不錯的吧,哈哈,我自己還是比較滿意的~項目地址已上傳至 github ,歡迎star、fork。那么下面我們就開始從無到有實現(xiàn)一下這個酷炫的進度效果吧。
項目地址SpecialProgressBar。

實現(xiàn)思路

仔細觀察下這個效果,它有不同的動態(tài)效果和不同的進度狀態(tài)組成,那么實現(xiàn)的思路就用效果切換的不同狀態(tài)來進行切換繪制,對應(yīng)數(shù)值的變化用到值動畫、Path、貝塞爾曲線、Camera與Matrix等相關(guān)工具,因為涉及的地方比較多,這里我就主要說下大體的實現(xiàn)思路以及相關(guān)注意點。

主要分五點來進行分析:

一、利用值動畫變換數(shù)值然后invalidate刷新界面,形成動畫效果。
二、在不同的臨界值切換不同的狀態(tài)
三、利用PathMeasure與Path來實現(xiàn)進度效果。
四、利用阻尼動畫實現(xiàn)進度條回彈效果。
五、利用Camera和Matrix實現(xiàn)進度框翻轉(zhuǎn)效果。

一、利用值動畫變換數(shù)值然后invalidate刷新界面,形成動畫效果

對位置、大小、顏色的切換主要使用的ValueAnimator來進行變化,看下代碼片段:

 ValueAnimator va = ValueAnimator.ofInt((int)(Math.min(getWidth(), getHeight())- mBgPaint.getStrokeWidth()*2)/2,(int) mBgPaint.getStrokeWidth());
            va.setInterpolator(new AnticipateInterpolator());
            va.setDuration(800);
            va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    int value = (Integer) animation.getAnimatedValue();
                    radiu = value;
                    center_scaleX = (1 - animation.getAnimatedFraction());
                    center_scaleY = (1 - animation.getAnimatedFraction());
                    invalidate();
                }
            });
            va.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {
                }
                @Override
                public void onAnimationEnd(Animator animation) {
                    state = STATE_READY_CHANGEING;//準(zhǔn)備階段
                    mBgPaint.setStyle(Paint.Style.STROKE);
                    mBgPaint.setColor(Color.BLACK);
                    changeStateReadyChanging();
                }
                @Override
                public void onAnimationCancel(Animator animation) {
                }
                @Override
                public void onAnimationRepeat(Animator animation) {
                }
            });
            va.start();

通過不同Interpolator插值器實現(xiàn)不同的運動效果,在AnimatorUpdateListener中改變數(shù)值,然后調(diào)用invalidat()方法,之后onDraw()方法會被調(diào)用,我們改變的數(shù)值在界面是就可以看到產(chǎn)生的動態(tài)效果了。

二、在不同的臨界值切換不同的狀態(tài)

考慮到動畫中涉及的動畫效果還是比較多的,可以用不同的狀態(tài)表示不同的動畫區(qū)間,在動畫結(jié)束時切換不同的狀態(tài),然后在invalidate方法中根據(jù)不同的狀態(tài)進行繪制,我們來看下吧:

    private static final int STATE_READY = 0;
    private static final int STATE_READY_CHANGEING = 1;
    private static final int STATE_READYING = 2;
    private static final int STATE_ERROR = 3;
    private static final int STATE_STARTING = 4;
    private static final int STATE_SUCCESS = 5;
    private static final int STATE_BACK = 6;
    private static final int STATE_BACK_HOME = 7;
    private static final int DONE = 8;

這里定義了九種狀態(tài),代表不同的動畫效果區(qū)間,根據(jù)這些狀態(tài)來進行動態(tài)切換繪制:

switch (state) {
            case STATE_BACK_HOME:
            case STATE_READY:
                p.reset();
                mBgPaint.setStyle(Paint.Style.FILL);

                p.addCircle(getWidth() / 2, getHeight() / 2, radiu, Path.Direction.CCW);
                canvas.drawPath(p, mBgPaint);
                matrix.reset();
                matrix.setScale(center_scaleX, center_scaleY);
                matrix.preTranslate(0,0);
                matrix.postTranslate(getWidth() / 2 - downloadBitmap.getWidth() / 2*Math.max(center_scaleX,center_scaleY), getHeight() / 2 - downloadBitmap.getHeight() / 2*Math.max(center_scaleX,center_scaleY));

                canvas.drawBitmap(downloadBitmap, matrix, mBgPaint);
                break;
            case STATE_READY_CHANGEING:
                p.reset();
                p.moveTo(startX, startY);
                p.lineTo(endX, endY);
                canvas.drawPath(p, mBgPaint);
                break;
                
                ...
          }

這里的狀態(tài)切換可以說是整個動畫切換的核心,通過對不同狀態(tài)的切換,然后對應(yīng)切換不同的值動畫,實現(xiàn)整個效果的動態(tài)銜接。

三、利用PathMeasure與Path來實現(xiàn)進度效果

PathMeasure作為一個輔助工具,在對Path路徑進行處理時是很方便的,我們來看下它吧:

setPath(Path path, boolean forceClosed)關(guān)聯(lián)一個Path
isClosed() 是否閉合
getLength() 獲取Path的長度
nextContour() 跳轉(zhuǎn)到下一個輪廓
getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo)截取路徑片段
getPosTan(float distance, float[] pos, float[] tan)獲取指定長度的位置坐標(biāo)及該點切線值
getMatrix(float distance, Matrix matrix, int flags)獲取指定長度的位置坐標(biāo)及該點Matrix

我們這里重點關(guān)注getSegment和getPosTan方法,

getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo),相關(guān)參數(shù):startD 開始截取位置距離 Path 起點的長度,stopD 結(jié)束截取位置距離 Path 起點的長度,dst 截取的 Path 將會添加到 dst 中,startWithMoveTo 起始點是否使用 moveTo。

在進度條變化的時候我們就使用這個方法動態(tài)的截取從開始位置到當(dāng)前位置的Path值,截取成功dst中就用截取路徑的值,然后調(diào)用drawPath方法繪制出進度效果。

需要注意的是:在安卓4.4或者之前的版本,在默認開啟硬件加速的情況下,更改 dst 的內(nèi)容后可能繪制會出現(xiàn)問題,請關(guān)閉硬件加速或者給 dst 添加一個單個操作,例如: dst.rLineTo(0, 0)。

getPosTan (float distance, float[] pos, float[] tan)
相關(guān)參數(shù):
distance 距離 Path 起點的長度
pos 該點的坐標(biāo)值
tan 該點的正切值

這里我們用這個方法來獲取當(dāng)前點的坐標(biāo)值,如果獲取成功,pos中就有坐標(biāo)值了,通過這個坐標(biāo)值來動態(tài)改變進度框和進度文字的位置。

四、利用阻尼動畫實現(xiàn)進度條回彈效果

開始進度前進度條有個回彈的效果,這里我們使用的阻尼效果,主要用設(shè)置插值器動態(tài)改變二階貝塞爾曲線的定點,定點位置的改變,形成整個路徑效果的改變。
阻尼插值器參考網(wǎng)上的實現(xiàn),我們看下主要實現(xiàn):

public DampingInterpolator(int count, float overshoot) {
        setOverShootCount(count);
        setOverShootPercent(overshoot);
    }

    public void setOverShootCount(int count) {
        mCount = Math.max(1, count);
        mRegion = (float) (Math.PI * 2 * (mCount - 1) + Math.PI / 2 * 3);
        mOvershootModulus = (float) Math.pow(mOvershootPercent, mRegion
                / Math.PI);
    }

    public void setOverShootPercent(float overshoot) {
        mOvershootPercent = Math.max(0, Math.min(1, overshoot));
       /*
        * 當(dāng) t * mRegion = Math.PI 的時候,達到第一次過沖的峰值, 則 t = Math.PI / mRegion 。 且此時
        * mOvershootModulus^t = mOvershootPercent , 所以 mOvershootModulus =
        * Math.pow(mOvershootPercent, 1 / t) , 即 mOvershootModulus =
        * Math.pow(mOvershootPercent, mRegion / Math.PI) 。
        */
        mOvershootModulus = (float) Math.pow(mOvershootPercent, mRegion
                / Math.PI);
    }
     @Override
    public float getInterpolation(float t) {
        if (t <= 0) {
            return 0;
        }
        if (t >= 1) {
            return 1;
        }
        return (float) (1 - Math.pow(mOvershootModulus, t)
                * Math.cos(mRegion * t));
    }

將阻尼插值器設(shè)置給我們要開啟的值動畫,改變二階貝塞爾曲線的定點,定點的來回回彈,最終形成曲線的來回回彈。

五、利用Camera和Matrix實現(xiàn)進度框翻轉(zhuǎn)效果

在失敗和成功時,進度框有個沿X軸和沿Y軸旋轉(zhuǎn)的效果,如果這里單單使用matrix不能實現(xiàn)效果,僅僅是在平面沿Z軸旋轉(zhuǎn)的。為了實現(xiàn)整個效果,我們使用Camera和Matrix來進行實現(xiàn),調(diào)用camera的roateX和roateY方法進行旋轉(zhuǎn)。

看下具體代碼:

                camera.save();
                camera.rotateY(rotateY);
                camera.getMatrix(cameraMatrix);
                camera.restore();

                cameraMatrix.preTranslate(0, -loadingBitmap.getHeight() / 2);
                cameraMatrix.postTranslate(POS[0], POS[1] - loadingBitmap.getHeight() / 2);
                canvas.drawBitmap(loadingBitmap, cameraMatrix, mBgPaint);

我們在調(diào)用rotateY方法后獲取到Matrix,然后調(diào)用canvas的drawBitmap方法來動態(tài)改變進度框的位置和文字的位置,一個動態(tài)效果就出來啦~

這里主要把主要的難點和主題思路縷了一下,如果要關(guān)注具體細節(jié),可查看源碼。
【github地址:https://github.com/zhangke301...】如果喜歡,歡迎star、fork。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/65052.html

相關(guān)文章

  • JParticles 2.0 發(fā)布,打造酷的粒子特效

    摘要:我們一貫的理念我們我笑哭一貫的理念是信仰和。第一點視差粒子幾行代碼為了看起來更簡潔,定義視差粒子層數(shù)的屬性就省略了,因為本身它就是層,也挺好的。演示四層,為了讓大家能更了解屬性的使用方法。又高大上,又可以緩解加載的等待心情。 JParticles 2.0 發(fā)布,打造炫酷的粒子特效。不好意思哈,在這么繁花似錦的世界里,標(biāo)題不得不取得吸引眼球一點哈,不然...還是不啰嗦了,我們進入正題吧s...

    tinna 評論0 收藏0

發(fā)表評論

0條評論

pekonchan

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<