以熟悉android的卡通。一个补间动画能执行同样名目繁多简单的变换(位置、大小、旋转角度以及透明度)关于一个视图对象的习性。

前言:
为熟悉android的卡通,看了郑钦洪_的iOS中旋转加载动画的实现,虽然他是为IOS的,但也是发生借鉴的处之(好吧,就是他让我写一个近乎的动画,赶紧上客那边点赞喜欢!他说
每10只爱慕叫自家同样片钱,蚊子腿更小吗是肉啊)。

补间动画

可以动用补间动画系统实施补间动画。补间动画计算动画相关的消息包括开接触、结束点、大小、旋转角度和任何同动画片相关的共同点。

一个补间动画能执行同样多样简单的转换(位置、大小、旋转角度与透明度)关于一个视图对象的性。所以,如果出一个TextView,你得给文本移动、旋转、放大、缩小。如果产生背景图片,背景图片将同文书一起让移。

补间动画可以透过XML文件要Android代码,推荐下XML文件。因为可读性更好,重用性更好,比硬编码更好替换。

每一个换获得一个切实变换的参数集合(开始大小,结束大小,开始角度,结束角度等等)和组成部分常见的参数(开始时间,时长)。为了要几只转移而起,使其的起来时一致;为了顺序执行,让开始日长变换执行之光阴。

补间动画的XML文件在res/anim目录下。该公文来号移根元素<alpha>,<scale>,<translate>,<rotate>,插值器元素或<set>。为了要变换顺序执行,必须设置startOffset属性。如下:

图片 1

exam1

屏幕坐标:左上角为(0,0),向右侧、向下多。

一部分价值,比如pointX,能确定相对自身还是相对父控件的关系。根据需要选择合适的格式(50乎相对父控件的50%,50%啊相对自身之50%)。

代码调用res/anim目录下之hyperspace_jump.xml动画:

ImageView
spaceshipImage=(ImageView)findViewById(R.id.spaceshipImage);

Animation
hyperspaceJumpAnimation=AnimationUtils.loadAnimation(this,R.anim.hyperspace_jump);

spaceshipImage.startAnimation(hyperspaceJumpAnimation);

startAnimation()可以利用如下方式代替:

给动画设置一个发端日Animation.setStartTime(),然后给视图设置动画View.setAnimation()。

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

透明度动画:

XML:res/anim/anim_alpha.xml

<alpha

        android:duration=”300″

        android:fromAlpha=”0.0″

        android:toAlpha=”1.0″/>

Animation
animation=AnimationUtils.loadAnimation(this,R.anim.anim_alpha);

imageView.startAnimation(animation);

注:

fromAlpha:动画开始经常的透明度;0.0晶莹剔透,1.0未透明。

toAlpha:动画结束时透明度;0.0晶莹剔透,1.0休透明。

Android Code:

AlphaAnimation localAlphaAnimation =new AlphaAnimation(0.0,1.0);

localAlphaAnimation.setDuration(300);

imageView.startAnimation(localAlphaAnimation);

waitingviw.gif

缩放动画:

XML:res/anim/anim_scale.xml

<scale

        android:duration=”300″

        android:fromXScale=”0.0″

        android:fromYScale=”0″

        android:pivotX=”50%”

        android:pivotY=”50%”

        android:toXScale=”1.0″

        android:toYScale=”1.0″/>

Animation
animation=AnimationUtils.loadAnimation(this,R.anim.anim_scale);

imageView.startAnimation(animation);

注:

fromXScale:开始时横向(X轴)的分寸;1.0依赖无改动。fromYScale同理。

toXScale:动画结束时纵向(Y轴)的大小;1.0靠没有改变。toYScale同理。

pivotX:对象缩放时,X轴坐标保持不转换的位置。pivotY同理。

Android Code:

ScaleAnimation localScaleAnimation =new
ScaleAnimation(0.0,1.0,0.0,1,0.5F,0.5F);

localScaleAnimation.setDuration(300);

imageView.startAnimation(localScaleAnimation);

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

盘动画:

XML:res/anim/anim_rotate.xml

<rotate

        android:duration=”300″

        android:fromDegrees=”0.0″

        android:toDegrees=”90.0″

        android:pivotX=”50%”

        android:pivotY=”50%”/>

Animation
animation=AnimationUtils.loadAnimation(this,R.anim.anim_rotate);

imageView.startAnimation(animation);

Android Code:

RotateAnimation rotateAnimation=new
RotateAnimation(0.0,
90.0, 50%, 50%);

rotateAnimation.setDuration(300);

imageView.startAnimation(rotateAnimation);

注:

构造函数:RotateAnimation(float fromDegrees, float toDegrees, int
pivotXType, float pivotXValue, int pivotYType, float pivotYValue)

pivotXType:用于描述pivotXValue的品类。

Animation.ABSOLUTE, 一个具体的数值;

Animation.RELATIVE_TO_SELF,相对自身的比例;

Animation.RELATIVE_TO_PARENT,相对父控件的百分比。

pivotXValue:一个现实的价后百分比,含义由pivotXType决定。

思路

各类移动画:

XML:res/anim/anim_translate.xml

<translate

        android:fromXDelta=”0%”

        android:toXDelta=”100%”

        android:duration=”300″/>

Animation
animation=AnimationUtils.loadAnimation(this,R.anim.anim_translate);

imageView.startAnimation(animation);

注:

fromXDelta:浮点数与比例,开始经常X轴的偏移量。表达方式:使用如素相对于健康职务,如:”5″;使用比例相对于元素自身之大幅度,如”5%”,或者相对于父亲控件的增幅,如”5%p”。formYDelta同理。

toXDelta:结束时X轴的偏移量。toYDelta 同理。

Android Code:

TranslateAnimation translateAnimation=new
TranslateAnimation(Animation.RELATIVE_TO_SELF,0.0f,
Animation.RELATIVE_TO_SELF,1.0f,Animation.RELATIVE_TO_SELF,0.0f,
Animation.RELATIVE_TO_SELF,0.0f);

translateAnimation.setDuration(300);

imageView.startAnimation(translateAnimation);

卡通循环:

图片 2

circu_anim

注:

duration:动画持续的时空,毫秒;

fillAfter:动画结束时,是否终止在结尾一轴;

fillBefore:动画结束时,是否停留在率先帧;

repeatCount:动画循环的次数,默认为 0 次于不循环,-1
(Animation.INFINITE)为极其循环;

repeatMode:循环的模式,Animation.REVERSE是打平软动画结束起,Animation.RESTART是起动画的起来处于循环;

interpolator:插值器。

  • 先是使起三单小圆
  • 独家实现三只小完美之动画
  • 何以方便的显得动画

插值器( Interpolators)

下面的说明指定每个插值器使用的资源:

图片 3

interpolator

以XML文件被,通过android:interpolator属性使用。如:

<set
android:interpolator=”@android:anim/accelerate_interpolator”>

</set>

Android Code:

RotateAnimation
rotateAnimation=newRotateAnimation(0.0,
90.0, 50%, 50%);

rotateAnimation.setDuration(300);

rotateAnimation.setInterpolator(new
AccelerateInterpolator());//越转越快

imageView.startAnimation(rotateAnimation);

插值器效果:

AccelerateDecelerateInterpolator():开始和终结慢,中间加速。

AccelerateInterpolator():刚开头慢,一直加速。

AnticipateInterpolator():开始走下坡路,然后急速向前。

AnticipateOvershootInterpolator():开始走下坡路,然后急速向前,超过目标价,再回到目标价。

BounceInterpolator():最后反弹。

CycleInterpolator(float cycles):循环指定的次数,速率随正弦曲线变化。

DecelerateInterpolator()、DecelerateInterpolator(float
factor):一开头不久,然后减速;factor:速度不同的品位。

LinearInterpolator():速率不转换。

OvershootInterpolator()、OvershootInterpolator(float
tension):急速向前,超过目标价,然后回;tension:超过的计量。

问题:

进过补间动画变换的目标只是是外部(大小、位置、透明度等)发生了改动,对象的本来属性并未改变,事件响应的职位也也改变。


一.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 的动画片,可能发许多地方理解错需要改善,欢迎大家留言。

相关文章