Android自定義加載動(dòng)畫-感染體

Android自定義動(dòng)畫系列七,今天來分享第七個(gè)自定義Loading動(dòng)畫(InfectionBallBuilder)笤昨,看上去感覺有種病毒源被感染的感覺,所以名字就叫感染體,這個(gè)動(dòng)畫做出來的效果印衔,我不怎么滿意,但是實(shí)現(xiàn)方式還是可以介紹介紹的姥敛。效果圖如下:

GIF有點(diǎn)大奸焙,手機(jī)流量請(qǐng)三思。

效果圖

演示效果動(dòng)畫

介紹

首先依舊是聲明,我做這些動(dòng)畫的初衷是為了學(xué)習(xí)和分享与帆,所以希望大家可以指點(diǎn)錯(cuò)誤了赌,讓我更好的進(jìn)步。(系列加載動(dòng)畫的截止時(shí)間:我放棄的時(shí)候)鲤桥。

最近清明放假揍拆,我也給我自己放了一個(gè)假,放松之余茶凳,玩了幾天幾夜的 王者榮耀 ??嫂拴。 五黑上分的感覺--爽歪歪呀。假期的最后一天了贮喧,收收心筒狠,繼續(xù)來一波動(dòng)畫。

上一個(gè)動(dòng)畫鏈接:Android自定義加載動(dòng)畫-顫抖吧箱沦!球球

言歸正傳辩恼,開始新的動(dòng)畫。

正文

這里先把之前一個(gè)動(dòng)畫進(jìn)行了簡(jiǎn)單的重構(gòu)谓形,然后提取了一個(gè)基類 BaseBallBuilder 灶伊,包含了畫筆的初始化,貝塞爾曲線畫圓方法寒跳,以及圓點(diǎn)內(nèi)部類聘萨。具體的實(shí)現(xiàn)方法可以見上一個(gè)動(dòng)畫,或者前往Github上進(jìn)行查看童太,這里就不做具體說明了米辐。

abstract class BaseBallBuilder extends ZLoadingBuilder
{
    //貝塞爾曲線常量
    private static final float                   PROP_VALUE  = 0.551915024494f;
    //小球點(diǎn)集合
    protected final      LinkedList<CirclePoint> mBallPoints = new LinkedList<>();
    //畫筆
    protected Paint mPaint;

    /**
     * 初始化畫筆
     */
    protected void initPaint(float lineWidth)
    {
      ...
    }

    /**
     * p10    p9      p8
     * ------  ------
     * p11                     p7
     * |                       |
     * |                       |
     * p0 |      (0,0)         | p6
     * |                       |
     * |                       |
     * p1                      p5
     * ------  ------
     * p2      p3      p4
     */
    protected final void initPoints(float ballR)
    {
     ...
    }

    protected final void drawBall(Canvas canvas, Path path, Paint paint)
    {
        ...
    }

    /**
     * 圓點(diǎn)內(nèi)部類
     */
    static class CirclePoint
    {
       ...
    }
}

這里開始今天的正題了 InfectionBallBuilder ,部分源碼如下书释,具體步驟介紹就都寫在注釋里面了翘贮。很多方式都和前面的動(dòng)畫介紹類似,大家可以往前翻看爆惧。因?yàn)閯?dòng)畫簡(jiǎn)單所以我這里就偷個(gè)懶狸页,不再一一分析了。

public class InfectionBallBuilder extends BaseBallBuilder
{
    //動(dòng)畫間隔時(shí)間
    private static final long DURATION_TIME   = 888;
    private static final long DURATION_TIME_1 = 222;
    private static final long DURATION_TIME_2 = 333;
    private static final long DURATION_TIME_3 = 1333;
    private static final long DURATION_TIME_4 = 1333;
    //最終階段
    private static final int  FINAL_STATE     = 4;
    private static final int  SUM_POINT_POS   = 3;
    private float mBallR;
    private Path  mPath;
    //當(dāng)前動(dòng)畫階段
    private int mCurrAnimatorState = 0;
    //每個(gè)小球的偏移量
    private float mCanvasTranslateOffset;

    @Override
    protected void initParams(Context context)
    {
        mBallR = getAllSize() / SUM_POINT_POS;
        mCanvasTranslateOffset = getIntrinsicWidth() / SUM_POINT_POS;
        mPath = new Path();
        initPaint(5);
        initPoints(mBallR);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        drawBall(canvas);
    }

    /**
     * 繪制小球
     *
     * @param canvas
     */
    private void drawBall(Canvas canvas)
    {
        canvas.save();
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        canvas.translate(0, -mCanvasTranslateOffset);
        super.drawBall(canvas, mPath, mPaint);
        canvas.restore();
    }

    @Override
    protected void computeUpdateValue(ValueAnimator animation, @FloatRange(from = 0.0, to = 1.0) float animatedValue)
    {
        float offset = mCanvasTranslateOffset;
        switch (mCurrAnimatorState)//這里分階段對(duì)每個(gè)圓點(diǎn)進(jìn)行偏移量設(shè)置
        {
            case 0:
                animation.setDuration(DURATION_TIME);
                animation.setInterpolator(new AccelerateInterpolator());
                mBallPoints.get(2).setOffsetY(animatedValue * offset);
                mBallPoints.get(3).setOffsetY(animatedValue * offset);
                mBallPoints.get(4).setOffsetY(animatedValue * offset);
                break;
            case 1:
                animation.setDuration(DURATION_TIME_1);
                animation.setInterpolator(new LinearInterpolator());
                mBallPoints.get(5).setOffsetY(animatedValue * offset);
                mBallPoints.get(6).setOffsetY(animatedValue * offset);
                mBallPoints.get(7).setOffsetY(animatedValue * offset);
                mBallPoints.get(1).setOffsetY(animatedValue * offset);
                mBallPoints.get(0).setOffsetY(animatedValue * offset);
                mBallPoints.get(11).setOffsetY(animatedValue * offset);
                break;
            case 2:
                animation.setDuration(DURATION_TIME_2);
                animation.setInterpolator(new AccelerateInterpolator());
                for (int i = 0; i < mBallPoints.size(); i++)
                {
                    if (i > 10 || i < 8)
                    {
                        mBallPoints.get(i).setOffsetY(animatedValue * offset + offset);
                    }
                    else
                    {
                        mBallPoints.get(i).setOffsetY(animatedValue * offset);
                    }
                }
                break;
            case 3:
                animation.setDuration(DURATION_TIME_3);
                animation.setInterpolator(new DecelerateInterpolator());

                mBallPoints.get(8).setOffsetY(animatedValue * offset + offset);
                mBallPoints.get(9).setOffsetY(animatedValue * offset + offset);
                mBallPoints.get(10).setOffsetY(animatedValue * offset + offset);


                mBallPoints.get(5).setOffsetX(animatedValue * offset);
                mBallPoints.get(6).setOffsetX(animatedValue * offset);
                mBallPoints.get(7).setOffsetX(animatedValue * offset);
                mBallPoints.get(1).setOffsetX(-animatedValue * offset);
                mBallPoints.get(0).setOffsetX(-animatedValue * offset);
                mBallPoints.get(11).setOffsetX(-animatedValue * offset);
                break;
            case 4:
                animation.setDuration(DURATION_TIME_4);
                mPaint.setAlpha((int) ((1 - animatedValue) * 255));
                break;
        }
    }

    @Override
    public void onAnimationRepeat(Animator animation)
    {
        if (++mCurrAnimatorState > FINAL_STATE)
        {//還原到第一階段
            mCurrAnimatorState = 0;
            for (CirclePoint point : mBallPoints)
            {
                point.setOffsetY(0);
                point.setOffsetX(0);
            }
            mPaint.setAlpha(255);
        }
    }

}

總結(jié)

小伙伴們扯再,要是想看更多細(xì)節(jié)肴捉,可以前往文章最下面的Github鏈接,如果大家覺得ok的話叔收,希望能給個(gè)喜歡齿穗,最渴望的是在Github上給個(gè)star。謝謝了饺律。

如果大家有什么更好的方案窃页,或者想要實(shí)現(xiàn)的加載效果,可以給我留言或者私信我,我會(huì)想辦法實(shí)現(xiàn)出來給大家脖卖。謝謝支持乒省。

Github:zyao89/ZCustomView

作者:Zyao89;轉(zhuǎn)載請(qǐng)保留此行畦木,謝謝袖扛;

個(gè)人博客:https://zyao89.cn

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市十籍,隨后出現(xiàn)的幾起案子蛆封,更是在濱河造成了極大的恐慌,老刑警劉巖勾栗,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惨篱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡围俘,警方通過查閱死者的電腦和手機(jī)砸讳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來界牡,“玉大人簿寂,你說我怎么就攤上這事∷尥觯” “怎么了陶耍?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)她混。 經(jīng)常有香客問我,道長(zhǎng)泊碑,這世上最難降的妖魔是什么坤按? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮馒过,結(jié)果婚禮上臭脓,老公的妹妹穿的比我還像新娘。我一直安慰自己腹忽,他們只是感情好来累,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著窘奏,像睡著了一般嘹锁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上着裹,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天领猾,我揣著相機(jī)與錄音,去河邊找鬼。 笑死摔竿,一個(gè)胖子當(dāng)著我的面吹牛面粮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播继低,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼熬苍,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了袁翁?” 一聲冷哼從身側(cè)響起柴底,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎梦裂,沒想到半個(gè)月后似枕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡年柠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年凿歼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冗恨。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡答憔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出掀抹,到底是詐尸還是另有隱情虐拓,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布傲武,位于F島的核電站蓉驹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏揪利。R本人自食惡果不足惜态兴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疟位。 院中可真熱鬧瞻润,春花似錦、人聲如沸甜刻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽得院。三九已至傻铣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間祥绞,已是汗流浹背矾柜。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工阱驾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人怪蔑。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓里覆,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親缆瓣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子喧枷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,133評(píng)論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件弓坞、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,103評(píng)論 4 62
  • “所以金剛經(jīng)上說要無人相隧甚,無我相,無眾生相渡冻,無壽者相戚扳。”白衣書生說完族吻,拿起面前的茶杯一飲而盡帽借。禪師點(diǎn)頭,為書生...
    山撼瑁花開閱讀 279評(píng)論 0 0
  • 當(dāng)橘子失去了酸甜 你還會(huì)為她沖動(dòng)嗎 還是你味覺錯(cuò)亂了 怎么都嘗不出她的顏色 當(dāng)你圍坐在火爐旁 才開始懷念那漫溢赤膊...
    下午和風(fēng)閱讀 203評(píng)論 0 2
  • 七月砍艾,獅泉河畔的紅柳又開花了巍举,水鳥在河面時(shí)而低飛覓食時(shí)而翱翔展翅懊悯,魚兒在河里歡快地跳躍著歡唱著,羊兒安詳?shù)爻灾荩?..
    厚土高天閱讀 1,615評(píng)論 0 4