一個(gè)很有意思的自定義loading動(dòng)畫

這就是張圖片

本文原創(chuàng)砰粹,不能匿名轉(zhuǎn)載

這次這個(gè)自定義loading還是有點(diǎn)意思饭入,先看看效果圖:

在十多秒的時(shí)候有點(diǎn)錯(cuò)亂讥珍,因?yàn)槲抑讳浟四敲淳?/div>

1.直接上代碼(HopLoadingView)

package com.hadisi.hoploading;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

/**
 * Created by hadisi5216 on 2016/8/25.
 */

public class HopLoadingView extends View {
    private Paint mPaint;

    private int widthSpecSize;
    private int heightSpecSize;
    private int radius = 20;//小圓球半徑
    private int HLength = 100;//六邊形半徑
    private int maxMoveH = 60;//向外移送最長(zhǎng)距離
    private double moveH = 0;//向外移動(dòng)增量
    private int theCircle = -1;//那個(gè)圓球在作用

    private ValueAnimator animator;

    public HopLoadingView(Context context) {
        super(context);
        mPaint = new Paint();
    }

    public HopLoadingView(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    public HopLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(0xFFE6413A);
        mPaint.setAntiAlias(true);
        for (int i = 1; i <= 6; i++) {
            if (theCircle % 6 + 1 == i)
                canvas.drawCircle(widthSpecSize / 2 + (float) (Math.cos(Math.PI * i / 3) * (HLength + moveH)), heightSpecSize / 2 - (float) (Math.sin(Math.PI * i / 3) * (HLength + moveH)), radius, mPaint);
            else
                canvas.drawCircle(widthSpecSize / 2 + (float) Math.cos(Math.PI * i / 3) * HLength, heightSpecSize / 2 - (float) Math.sin(Math.PI * i / 3) * HLength, radius, mPaint);
        }
    }

    public void start() {
        if (animator != null)
            animator.cancel();
        animator = ValueAnimator.ofFloat(0f, (float) Math.PI * 6);
        animator.setDuration(3000);
        animator.setRepeatMode(ValueAnimator.RESTART);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                moveH = Math.abs(Math.sin((Float) animation.getAnimatedValue())) * maxMoveH;
                theCircle = (int) ((Float) animation.getAnimatedValue() / Math.PI) + 1;
                nvalidate();
            }
        });
        animator.start();
    }
}

2.聊聊我的思路

1、畫出那六個(gè)小圓;
2、讓小圓做向外移動(dòng)然后移回來(lái)的動(dòng)畫;
3、讓六個(gè)小圓依次循環(huán)動(dòng)畫。

1.畫出那六個(gè)小圓

圖畫的真丑

看上圖泳赋,六個(gè)小圓分別在六邊形的六個(gè)頂點(diǎn)衅鹿,我們定義六邊形的中心點(diǎn)為該控件的中心點(diǎn)(widthSpecSize / 2,heightSpecSize / 2),則圖中那個(gè)小圓的坐標(biāo)為(widthSpecSize / 2 + (float) Math.cos(Math.PI * i / 3) * HLength, heightSpecSize / 2 - (float) Math.sin(Math.PI * i / 3) * HLength)。其他幾個(gè)小圓的坐標(biāo)只要改變?yōu)閷?duì)應(yīng)的角度即可,如下代碼可以輕松畫出六個(gè)小圓:

for (int i = 1; i <= 6; i++) {
    canvas.drawCircle(widthSpecSize / 2 + (float) Math.cos(Math.PI * i / 3) * HLength, heightSpecSize / 2 - (float) Math.sin(Math.PI * i / 3) * HLength, radius, mPaint);
}

2.讓小圓做向外移動(dòng)然后移回來(lái)的動(dòng)畫
還是看上面那個(gè)圖捷犹,可以通過(guò)改變HLength的值來(lái)完成向外移動(dòng)然后移回來(lái)的動(dòng)畫枪孩;還有動(dòng)畫的軌跡有點(diǎn)正弦曲線的意思,嚴(yán)格來(lái)說(shuō)應(yīng)該是y=|sinx|函數(shù)對(duì)應(yīng)的曲線』僬祝看下圖隨著x的不斷變化茎芭,y的值在0和1之間變化趁仙。

y=|sinx|函數(shù)

可以使用屬性動(dòng)畫,讓ValueAnimator對(duì)象的變化范圍為(0f, (float) Math.PI),勻速循環(huán)播放

animator = ValueAnimator.ofFloat(0f, (float) Math.PI);
animator.setDuration(3000);
animator.setRepeatMode(ValueAnimator.RESTART);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setInterpolator(new LinearInterpolator());

再定義一個(gè)向外移動(dòng)的增量moveH,那么它的值應(yīng)該是下面旭蠕,其中maxMoveH為它能移動(dòng)的最大距離

moveH = Math.abs(Math.sin((Float) animation.getAnimatedValue())) * maxMoveH;

對(duì)應(yīng)的小圓的draw應(yīng)該為

canvas.drawCircle(widthSpecSize / 2 + (float) (Math.cos(Math.PI / 3) * (HLength + moveH)), heightSpecSize / 2 - (float) (Math.sin(Math.PI / 3) * (HLength + moveH)), radius, mPaint);

3.讓六個(gè)小圓依次循環(huán)動(dòng)畫
定義一個(gè)變量theCircle標(biāo)記那個(gè)小圓在運(yùn)動(dòng)捆蜀,讓ValueAnimator對(duì)象的變化范圍為(0f, (float) Math.PI * 6)呢蔫,則

theCircle = (int) ((Float) animation.getAnimatedValue() / Math.PI) + 1;

這樣theCircle的值會(huì)ValueAnimator對(duì)象的變化在1,2卷胯,3,4狭姨,5暖眼,6之間循環(huán)司澎,此時(shí)畫小圓的方法變?yōu)?/p>

for (int i = 1; i <= 6; i++) {
    if (theCircle % 6 + 1 == i)
        canvas.drawCircle(widthSpecSize / 2 + (float) (Math.cos(Math.PI * i / 3) * (HLength + moveH)), heightSpecSize / 2 - (float) (Math.sin(Math.PI * i / 3) * (HLength + moveH)), radius, mPaint);
    else
        canvas.drawCircle(widthSpecSize / 2 + (float) Math.cos(Math.PI * i / 3) * HLength, heightSpecSize / 2 - (float) Math.sin(Math.PI * i / 3) * HLength, radius, mPaint);
}

總結(jié):再?gòu)?fù)雜的需求,分解為N個(gè)獨(dú)立的小需求,一個(gè)個(gè)干掉它杠步,它就沒(méi)那么復(fù)雜了泣刹。喜歡您就戳下下面的喜歡!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末藕畔,一起剝皮案震驚了整個(gè)濱河市马僻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌注服,老刑警劉巖韭邓,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異溶弟,居然都是意外死亡女淑,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門辜御,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鸭你,“玉大人,你說(shuō)我怎么就攤上這事擒权「ぞ蓿” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵碳抄,是天一觀的道長(zhǎng)愉老。 經(jīng)常有香客問(wèn)我,道長(zhǎng)纳鼎,這世上最難降的妖魔是什么俺夕? 我笑而不...
    開(kāi)封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮贱鄙,結(jié)果婚禮上劝贸,老公的妹妹穿的比我還像新娘。我一直安慰自己逗宁,他們只是感情好映九,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著瞎颗,像睡著了一般件甥。 火紅的嫁衣襯著肌膚如雪捌议。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天引有,我揣著相機(jī)與錄音瓣颅,去河邊找鬼。 笑死譬正,一個(gè)胖子當(dāng)著我的面吹牛宫补,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播曾我,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼粉怕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了抒巢?” 一聲冷哼從身側(cè)響起贫贝,我...
    開(kāi)封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蛉谜,沒(méi)想到半個(gè)月后稚晚,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡悦陋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年蜈彼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俺驶。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡幸逆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出暮现,到底是詐尸還是另有隱情还绘,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布栖袋,位于F島的核電站拍顷,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏塘幅。R本人自食惡果不足惜昔案,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望电媳。 院中可真熱鬧踏揣,春花似錦、人聲如沸匾乓。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至娱局,卻和暖如春彰亥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背衰齐。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工任斋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人耻涛。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓仁卷,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親犬第。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

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