android 一个等待加载组合动画

前言:
为了熟悉android的动画,看了郑钦洪_的iOS中旋转加载动画的实现,虽然他是搞IOS的,但也是有借鉴之处的(好吧,就是他叫我写一个类似的动画,赶紧上他那里点赞喜欢!他说 每10个喜欢给我一块钱,蚊子腿再小也是肉啊)。

先上个GIF图
为了这个动画专门去下载了LICEcap,挺好用的工具

waitingviw.gif

github地址,欢迎大家提出修改意见

思路

  • 首先要有三个小圆
  • 分别实现三个小圆的动画
  • 如何方便的展示动画

一.CircleView的实现

自定义一个圆类,有设置颜色,半径,以及圆上显示的文字的方法。


    protected void onDraw(Canvas canvas) {

        //画笔设置颜色
        mPaint.setColor(circleColor);
        mPaint.setAntiAlias(true);
        //画一个圆
        canvas.drawCircle(mViewWidth / 2, mViewHeight / 2, circleRadius, mPaint);
        //设置文字
        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()方法时,返回的高和宽要根据圆的半径来设,这样能使整个view最贴近整个圆。**

二.各个圆的动画的实现

先分解一下整个动画过程,整个动画可以分解为三个阶段

  • 第一阶段
第一阶段.gif
  1. 中间小球从1倍的大小缩放到0.7倍的大小
scale_small = new ScaleAnimation(1f, 0.7f, 1f, 0.7f, circleRadius, circleRadius);```
 -  左边的小球从1倍的大小缩放到0.7倍的大小 ,并且绕着中间小球旋转360度,同时向左边4倍于半径距离移动 ,缩小的动画复用上面的 

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

 - 右边的小球从1倍的大小缩放到0.7倍的大小 ,并且绕着中间小球旋转360度,同时向右边4倍于半径距离移动 ,缩小的动画同样复用上面的 

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


分别创建三个动画集,添加各自的动画,并且设定动画时间以及``setFillAfter(true)``,使第一阶段动画结束后保持在结束的位置,使第二阶段的动画能够连接上。分别给小球设定动画,并且给其中一个动画集设定监听事件,结束播放第二阶段的动画。

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倍于半径距离移动 ,放大的动画复用上面的
left_translate_to_right = new TranslateAnimation(-rotatoRadius, 0, 0, 0);
  • 右边的小球从0.7倍的大小放大到1倍的大小 同时向左边4倍于半径距离移动 ,放大的动画同样复用上面的
right_translate_to_left = new TranslateAnimation(rotatoRadius, 0, 0, 0);

再次分别创建三个动画集,添加各自的动画,并且设定动画时间以及setFillAfter(true),使第二阶段动画结束后保持在结束的位置,使第一阶段的动画能够连接上。分别给小球设定动画,并且给其中一个动画集设定监听事件,结束播放第一阶段的动画,这里的监听事件类似于第一阶段的,就不贴出代码了。


  • 第三阶段
    第三阶段.gif
  • 在任意一个阶段触发了结束动画的事件(可以在前面两个阶段处看到一个布尔类型的 dismiss标志来给动画集添加消失动画),给那个阶段的每个动画集添加如下几个动画:
    让小球从1倍的大小放大到2倍的大小
scale_bigger = new ScaleAnimation(1f, 2f, 1f, 2f, circleRadius, circleRadius);

让小球透明度从 1 到 0 变化

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

给其中一个动画(scale_bigger /alpha_low )设定监听事件,当结束时清空所有动画,设定小球的透明度为 0(使窗口消失时不至于看到小球),同时调用对应的回调方法

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) {

            }
        });

三.实现一句话让该等待加载动画附着于页面任意一个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>

先实例化一个静态的对象,通过showWaitingView()方法来调用该实例,并实现在一个Popupwindow中显示,该Popupwindow附着在传来的View上。


结束语
刚开始接触android 的动画,可能有许多地方理解错误需要改进,欢迎大家留言。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • Animation Animation类是所有动画(scale、alpha、translate、rotate)的基...
    四月一号阅读 1,868评论 0 10
  • 三年五载的, 她,也在慢慢地老去。 裂开的墙面,剥离的泥土, 是一道道皱纹。也是曾经 一个时代,最后所能留下的印记...
    特朗斯特罗姆的学徒阅读 184评论 0 0