Android动画的总结

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


一、老版动画
老版动画主要集中在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,真是好麻烦=。=  希望能保持这样的习惯

猜你喜欢

转载自blog.csdn.net/wangzici/article/details/78149356