动画在工作中虽然用到的地方还不多,但是如果加上动画,效果还是很不错的。看了大神的blog之后总结一下其中的用法,方便以后在工作中使用()


一、老版动画
老版动画主要集中在android.view.animation中,如果需要在xml文件中使用,需要在res下新建anim文件夹
老版的动画分为逐帧动画和补间动画


①逐帧动画
就是一个图片一个图片的播放,可以设置每个图片的停留时间之类的,一般直接用xml来实现,这里是从(http://www.jianshu.com/p/420629118c10)copy的一小段逐帧代码,需要在drawable文件夹下新建
在Activity使用如下

ImageView animationImg1 = (ImageView) findViewById(R.id.animation1);
        animationImg1.setImageResource(R.drawable.frame_anim1);
        AnimationDrawable animationDrawable1 = (AnimationDrawable) animationImg1.getDrawable();
        animationDrawable1.start();



②补间动画


补间动画分为alpha、translate、scale、rotate,分别是透明度、位移、缩放、旋转


如需要某个图片放大一点的动画


<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="1.0"
    android:toXScale="1.5"
    android:fromYScale="1.0"
    android:toYScale="1.5"
    android:pivotX="50%"
    android:pivotY="50%" />

fromXScale:float,起始的X方向上相对自身的比例,如2.0 即放大一倍


pivoX:起点的X轴坐标,如:50 原点处加上50px,50% 原点处加上自身宽度的百分之五十,50%p 原点处加上父控件宽度的百分之五十



如果想要在代码中使用


Animation animation = AnimationUtils.loadAnimation(mContext, R.anim.scale_anim);
img = (ImageView) findViewById(R.id.img);
img.startAnimation(animation);



若是想直接在代码中动态使用,再设置如重复次数、是否在动画结束后停留在执行完的状态


RotateAnimation rotate = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotate.setRepeatMode(3);
rotate.setFillAfter(true);



若是需要动画混合使用的话,可以使用AnimationSet,该类也是继承自Animation


?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="true">
    <scale android:fromXScale="1"
        android:toXScale="1.2"
        android:fromYScale="1"
        android:toYScale="1.2"
        android:pivotX="50%"
        android:pivotY="50%"/>
    <alpha
        android:fromAlpha="0"
        android:toAlpha="1"/>
</set>




上面的代码就是在放大的同时,从透明到完全不透明的效果,至于xml文件如何在代码中使用,与上面的补间动画相同即可。


若需要在代码中动态使用AnimationSet,通过add方法添加补间动画即可,至于构造函数中的true,即为添加的所有补间动画是否共享AnimationSet设置的interpolator


AnimationSet animationSet1 = new AnimationSet(true);
        animationSet1.addAnimation(rotate);



二、属性动画


优点:可以对非View进行操作、实现非补间动画类型之外的动画、真正的改变属性


主要是来自于android.animation包中


主要有ValueAnimator与ObjectAnimator,其中后者继承了前者


①ValueAnimator


主要是对值进行改变


如下面的代码


ValueAnimator animator = ValueAnimator.ofFloat(1f,5f,3f);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                float currentValue = (Float) valueAnimator.getAnimatedValue();
                Log.i("wzt","currentValue = " + currentValue);
                invalidate();
            }
        });



打印出的currentValue应该是从1变化到5再变化到3的


我们可以通过实现一个TypeEvaluation接口,来告诉ValueAnimation如何去改变一个对象对应的值


如下,Point是我们自己创建的一个类,里面有x,y用于存储位置的信息


public class PointeEvaluator implements TypeEvaluator {
    @Override
    public Object evaluate(float v, Object o, Object t1) {
        Point startpoint = (Point) o;
        Point endpoint = (Point) t1;
        float startx = startpoint.getX();
        float starty = startpoint.getY();
        float endx = endpoint.getX();
        float endy = endpoint.getY();
        float currentx = startx + (v * (endx - startx));
        float currenty = starty + (v * (endy - starty));
        return new Point(currentx,currenty);
    }
}



可以声明ValueAnimator的时候,就可以在ofObject中使用了


接着通过在onAnimationUpdate中得到相应的对象,在自定义view里就可以根据得到的对象去绘图


ValueAnimator animator = ValueAnimator.ofObject(new PointeEvaluator(),new Point(RADIUS,RADIUS),new Point(getWidth()-RADIUS,getHeight()-RADIUS));
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                currentPoint = (Point) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });



②ObjectAnimator


如果以后在工作中需要用到动画的话,可能这会是使用最多的一个类,因为用起来相对于前面来说太方便了


它可以直接对任意对象的属性进行操作,如View的alpha属性


xml中的使用方式


<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:valueType="floatType"
    android:propertyName="alpha"
    android:valueFrom="0"
    android:valueTo="1"/>



若是使用AnimatorSet进行混合的话,xml如下,注意ordering表示该set内的子项是同时播放还是顺序播放。


<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together">
    <objectAnimator
        android:propertyName="rotation"
        android:valueType="floatType"
        android:valueFrom="0f"
        android:valueTo="360f"
        android:duration="1000"/>


    <set android:ordering="sequentially">
        <objectAnimator
            android:propertyName="alpha"
            android:valueType="floatType"
            android:valueFrom="1f"
            android:valueTo="0f"
            android:duration="500"/>
        <objectAnimator
            android:propertyName="alpha"
            android:valueType="floatType"
            android:valueFrom="0f"
            android:valueTo="1f"
            android:duration="500"/>
    </set>


</set>



使用时


ObjectAnimator temp = (ObjectAnimator) AnimatorInflater.loadAnimator(this,R.animator.object_animator);
Animator animator = AnimatorInflater.loadAnimator(this,R.animator.animator_mix);
animator.setTarget(imageView);



若是直接在java中动态使用


ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(imageView,"alpha",1f,0f,1f);
ObjectAnimator rolateAnimator = ObjectAnimator.ofFloat(imageView,"rotation",0f,360f);
AnimatorSet animationSet = new AnimatorSet();
animationSet.setDuration(1000);
animationSet.play(alphaAnimator).with(rolateAnimator);
animationSet.start();

上面的代码中AnimatorSet.play返回了一个AnimatorSet.Builder的实例,包括了下面几种方法


after  将一个动画放到之后执行


after(int)延迟执行


before 将一个动画放到动画之前执行


with  将这个动画一起执行


因此上面代码的逻辑就是alphaAnimator与rolateAnimator一起执行了



注意ObjectAnimator中如果需要修改其他属性的话,如Color,可以直接在View中新增Color的getter与setter,之后就可以通过如下一条代码使用了


ObjectAnimator anim = ObjectAnimator.ofObject(myAnimView, "color", new ColorEvaluator(),   
    "#0000FF", "#FF0000");


三、Interpolation


控制动画的变化速率,从而实现一种非线性的动画效果


主要就是通过实现Interpolator接口来实现,其中的getInterpolation里的v属性就是从0~1的一个变化过程


如下代码就是实现大小从0~1.2之后,再回到1的效果


public class MyInterpolator implements Interpolator {
    @Override
    public float getInterpolation(float v) {
        if (v < 0.8) {
            return (float) (v * 1.5 / 0.8);
        } else {
            return (float) (1.5 - v * 0.2);
        }
    }
}



其余还有很多系统自带的


如BounceInterpolator是模拟反弹的效果


textview.animate().x(500).y(500).setDuration(5000)  
        .setInterpolator(new BounceInterpolator());  
extview.animate().alpha(0f);

调用之后会直接启动动画的播放


以上就是关于安卓动画的一个小总结,最近才开始写blog,真是好麻烦=。=  希望能保持这样的习惯