android 一個等待加載組合動畫

前言:
為了熟悉android的動畫,看了鄭欽洪_的iOS中旋轉(zhuǎn)加載動畫的實現(xiàn),雖然他是搞IOS的,但也是有借鑒之處的(好吧,就是他叫我寫一個類似的動畫,趕緊上他那里點贊喜歡!他說 每10個喜歡給我一塊錢,蚊子腿再小也是肉啊)。

先上個GIF圖
為了這個動畫專門去下載了LICEcap,挺好用的工具

waitingviw.gif

github地址,歡迎大家提出修改意見

思路

  • 首先要有三個小圓
  • 分別實現(xiàn)三個小圓的動畫
  • 如何方便的展示動畫

一.CircleView的實現(xiàn)

自定義一個圓類,有設(shè)置顏色,半徑,以及圓上顯示的文字的方法。


    protected void onDraw(Canvas canvas) {

        //畫筆設(shè)置顏色
        mPaint.setColor(circleColor);
        mPaint.setAntiAlias(true);
        //畫一個圓
        canvas.drawCircle(mViewWidth / 2, mViewHeight / 2, circleRadius, mPaint);
        //設(shè)置文字
        if(mText!=null){
            mPaint.setTextSize(mViewHeight*7/8);
            float textWidth = mPaint.measureText(mText);
            float percent = (circleRadius * 2)/textWidth;
            mPaint.setColor(textColor);
            canvas.drawText(mText,mViewWidth /2 - textWidth/2,  
                                mViewHeight/2+mPaint.getTextSize()/3 ,mPaint);
        }

    }

** 注意重寫onMeasure()方法時,返回的高和寬要根據(jù)圓的半徑來設(shè),這樣能使整個view最貼近整個圓。**

二.各個圓的動畫的實現(xiàn)

先分解一下整個動畫過程,整個動畫可以分解為三個階段

  • 第一階段
第一階段.gif
  1. 中間小球從1倍的大小縮放到0.7倍的大小
scale_small = new ScaleAnimation(1f, 0.7f, 1f, 0.7f, circleRadius, circleRadius);```
 -  左邊的小球從1倍的大小縮放到0.7倍的大小 ,并且繞著中間小球旋轉(zhuǎn)360度,同時向左邊4倍于半徑距離移動 ,縮小的動畫復(fù)用上面的 

left_ratote = new RotateAnimation(359f, 0f, 3 * circleRadius, circleRadius);
left_translate_to_left = new TranslateAnimation(0, -rotatoRadius, 0, 0);

 - 右邊的小球從1倍的大小縮放到0.7倍的大小 ,并且繞著中間小球旋轉(zhuǎn)360度,同時向右邊4倍于半徑距離移動 ,縮小的動畫同樣復(fù)用上面的 

right_rotate = new RotateAnimation(359f, 0f, -circleRadius, circleRadius);
right_translate_to_right = new TranslateAnimation(0, rotatoRadius, 0, 0);


分別創(chuàng)建三個動畫集,添加各自的動畫,并且設(shè)定動畫時間以及``setFillAfter(true)``,使第一階段動畫結(jié)束后保持在結(jié)束的位置,使第二階段的動畫能夠連接上。分別給小球設(shè)定動畫,并且給其中一個動畫集設(shè)定監(jiān)聽事件,結(jié)束播放第二階段的動畫。

left_translate_rotate_scale.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            Log.e("wv", "left_translate_rotate_scale finish");

            if (!stop) {
                if (dismiss) {
                    //添加 消失動畫
                    addDismissAnima(mid_scale_big, left_translate_scale, right_translate_scale);

                }
                clear();

// 開始第二個動畫集
c1.startAnimation(mid_scale_big);
c2.startAnimation(left_translate_scale);
c3.startAnimation(right_translate_scale);

            }
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    });



***
- **第二階段**

![第二階段.gif](http://upload-images.jianshu.io/upload_images/853620-11669339398d267c.gif?imageMogr2/auto-orient/strip)
 1.  中間小球從0.7倍的大小放大到1倍的大小  

scale_big = new ScaleAnimation(0.7f, 1f, 0.7f, 1f, circleRadius, circleRadius);```

  • 左邊的小球從0.7倍的大小放大到1倍的大小 ,同時向右邊4倍于半徑距離移動 ,放大的動畫復(fù)用上面的
left_translate_to_right = new TranslateAnimation(-rotatoRadius, 0, 0, 0);
  • 右邊的小球從0.7倍的大小放大到1倍的大小 同時向左邊4倍于半徑距離移動 ,放大的動畫同樣復(fù)用上面的
right_translate_to_left = new TranslateAnimation(rotatoRadius, 0, 0, 0);

再次分別創(chuàng)建三個動畫集,添加各自的動畫,并且設(shè)定動畫時間以及setFillAfter(true),使第二階段動畫結(jié)束后保持在結(jié)束的位置,使第一階段的動畫能夠連接上。分別給小球設(shè)定動畫,并且給其中一個動畫集設(shè)定監(jiān)聽事件,結(jié)束播放第一階段的動畫,這里的監(jiān)聽事件類似于第一階段的,就不貼出代碼了。


  • 第三階段
    第三階段.gif
  • 在任意一個階段觸發(fā)了結(jié)束動畫的事件(可以在前面兩個階段處看到一個布爾類型的 dismiss標(biāo)志來給動畫集添加消失動畫),給那個階段的每個動畫集添加如下幾個動畫:
    讓小球從1倍的大小放大到2倍的大小
scale_bigger = new ScaleAnimation(1f, 2f, 1f, 2f, circleRadius, circleRadius);

讓小球透明度從 1 到 0 變化

  alpha_low = new AlphaAnimation(1f, 0f);

給其中一個動畫(scale_bigger /alpha_low )設(shè)定監(jiān)聽事件,當(dāng)結(jié)束時清空所有動畫,設(shè)定小球的透明度為 0(使窗口消失時不至于看到小球),同時調(diào)用對應(yīng)的回調(diào)方法

scale_bigger.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                c1.setAlpha(0f);
                c2.setAlpha(0f);
                c3.setAlpha(0f);
                clear();
                stop = true;
                listener.onFinish();
                Toast.makeText(context, "dismiss", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });

三.實現(xiàn)一句話讓該等待加載動畫附著于頁面任意一個View上

這里用到了單例模式的思想


    private static WaitingView wv;

    private OnFinish listener = new OnFinish() {

        @Override
        public void onFinish() {
            popupWindow.dismiss();
            wv.stop();
            wv.resetAnima();
        }
    };


    private static PopupWindow popupWindow;


    public static void showWaitingView(Context context, View view,int width,int height, int thecolor, float theradius,int thebackgroundColor ) {

        wv = new WaitingView(context);
        color = thecolor;
        circleRadius  = theradius;
        windowWidth = width;
        windowHeight = height;
        backgroundColor = thebackgroundColor;

        View layoutView = LayoutInflater.from(context).inflate(R.layout.pupop, null);
        layoutView.setBackgroundColor(backgroundColor);

        wv = (WaitingView) layoutView.findViewById(R.id.id_wv);

        wv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                wv.dismiss();

            }
        });


        popupWindow = new PopupWindow(layoutView, windowWidth, windowHeight,
                false);
        popupWindow.showAtLocation(view, Gravity.CENTER, 0, 0);
        wv.start();

    }
    public static boolean isExist() {
        return wv != null;
    }

    public static void close() {
        wv.dismiss();
    }

R.layout.pupop.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <network.scau.com.asimplewaitingdemo.WaitingView
        android:id="@+id/id_wv"
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

先實例化一個靜態(tài)的對象,通過showWaitingView()方法來調(diào)用該實例,并實現(xiàn)在一個Popupwindow中顯示,該Popupwindow附著在傳來的View上。


結(jié)束語
剛開始接觸android 的動畫,可能有許多地方理解錯誤需要改進(jìn),歡迎大家留言。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,523評論 25 708
  • Animation Animation類是所有動畫(scale、alpha、translate、rotate)的基...
    四月一號閱讀 1,936評論 0 10
  • 三年五載的, 她,也在慢慢地老去。 裂開的墻面,剝離的泥土, 是一道道皺紋。也是曾經(jīng) 一個時代,最后所能留下的印記...
    特朗斯特羅姆的學(xué)徒閱讀 219評論 0 0