android 一个等待加载组合动画

作者: 郑鸿翊 | 来源:发表于2015-10-11 23:50 被阅读9424次

    前言:
    为了熟悉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:https://img.haomeiwen.com/i853620/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 的动画,可能有许多地方理解错误需要改进,欢迎大家留言。

    相关文章

      网友评论

      • Eatbeer:这位前辈您好,我是一位初学者小白,敢问该程序需要import哪些包?
        郑鸿翊:https://github.com/zhygithub/ASimpleWaitingDemo

        import android.content.Context;
        import android.graphics.Color;
        import android.util.AttributeSet;
        import android.util.Log;
        import android.view.Gravity;
        import android.view.LayoutInflater;
        import android.view.View;
        import android.view.animation.AlphaAnimation;
        import android.view.animation.Animation;
        import android.view.animation.AnimationSet;
        import android.view.animation.RotateAnimation;
        import android.view.animation.ScaleAnimation;
        import android.view.animation.TranslateAnimation;
        import android.widget.PopupWindow;
        import android.widget.RelativeLayout;
        import android.widget.Toast;
      • 命运自认幽默:加油↖(^ω^)↗
      • 843fa938673e:谢谢分享
        郑鸿翊:@谷幽然 分享想法,共同进步,谢谢支持!

      本文标题:android 一个等待加载组合动画

      本文链接:https://www.haomeiwen.com/subject/nlqocttx.html