动画系列之属性动画

来源:互联网 发布:java软件工程师怎么考 编辑:程序博客网 时间:2024/04/28 06:01

一、简介

前面总结了视图动画的使用,下面来说说属性动画。
属性动画是API1(Android 3.0)才加入的动画。我们都知道视图动画不能真正的改变对象的属性,并不能满足我们的需求,此时属性动画就诞生了,而属性动画就是很好的对对象进行扩展,通过对对象的属性进行反射来实现动画。
优点:可以对任何对象进行动画。
缺点:

  1. 在API11之间无法使用, 只能借助第三方插件(nineoldandroids)。
  2. 由于是通过反射来实现的,所以必须提供属性的setter()方法, 如果需要获取初值,还需要提供getter()方法。

二、相关属性介绍

<set>  -----> AnimatorSet
android : ordering 表示集合中动画播放顺序  together : 同时播放 sequentially : 按照前后顺序播放

<animator> ----> ValueAnimator
android : duration  动画时间
android : valueFrom  动画开始值
android : valueTo  动画结束值
android : startOffset  动画的延迟时间 即多长时间后开始动画
android : repeatCount  动画重复的次数 默认值为0  -1 表示无限循环
android : repeatMode 表示动画重复的方式 restart 每次都是重新开始 reverse 表示逆向重复
android : valueType 表示android : propertyName 所指定属性的类型  intType floatType

<objectAnimator>----> ObjectAnimator 是ValueAnimator的子类
其他属性和<animator> 相同
android : propertyName 表示动画作用的属性名称
注意:如果propertyName  所指定的属性表示的是颜色, 则不需要指定valueType  类型, 系统会自动对颜色进行处理。

三、属性动画的实现

1. ObjectAnimator 的实现

ValueAnimatior的实现和ObjectAnimator实现类似, 就不举例。

 a、 xml形式实现

<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"android:duration="500"android:interpolator="@android:anim/accelerate_decelerate_interpolator"android:propertyName="rotation"android:repeatCount="1"android:repeatMode="reverse"android:valueFrom="0"android:valueTo="360"android:valueType="floatType" />
代码中引用
ObjectAnimator animator = (ObjectAnimator) loadAnimator(this, R.animator.object_animator);animator.setTarget(iv_anim);animator.start();

b、纯Java代码实现

ObjectAnimator animator = ObjectAnimator.ofFloat(iv_anim, "translationY", 100f, 300f);animator.setDuration(3000);animator.start();

2、组合动画的实现

a、xml形式实现

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"    android:ordering="sequentially">    <set>        <set android:ordering="sequentially">            <objectAnimator                android:duration="200"                android:propertyName="translationX"                android:repeatMode="reverse"                android:valueFrom="0"                android:valueTo="200" />            <objectAnimator                android:duration="200"                android:propertyName="translationX"                android:repeatMode="reverse"                android:valueFrom="200"                android:valueTo="0" />        </set>    </set>    <set >        <objectAnimator            android:duration="400"            android:propertyName="rotation"            android:repeatMode="reverse"            android:valueFrom="0"            android:valueTo="360" />        <set android:ordering="sequentially">            <objectAnimator                android:duration="200"                android:propertyName="translationX"                android:repeatMode="reverse"                android:valueFrom="0"                android:valueTo="-200" />            <objectAnimator                android:duration="200"                android:propertyName="translationX"                android:repeatMode="reverse"                android:valueFrom="-200"                android:valueTo="0" />        </set>    </set></set>
代码中引用

AnimatorSet animator = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.property_animator);animator.setTarget(iv_anim);animator.start();

b、纯Java代码实现

ObjectAnimator animator0 = ObjectAnimator.ofFloat(iv_anim, "alpha", 0.5F, 1F);ObjectAnimator animator1 = ObjectAnimator.ofFloat(iv_anim, "translationY", 200F, 0);ObjectAnimator animator2 = ObjectAnimator.ofFloat(iv_anim, "translationX", -200F, 0);AnimatorSet set = new AnimatorSet();set.setDuration(3000);set.setInterpolator(new BounceInterpolator());set.playTogether(animator0, animator1, animator2);set.start();

注意:此处是使用playTogether()方法让所用动画同事执行的,如果我们想让动画按照一定的顺序执行,可以调用play()方法来获取 AnimatorSet.Builder 实例,AnimatorSet.Builder 给我们提供了一下方法,用于控制动画执行 。

  • after(Animator anim) 将现有动画插入到传入动画之后执行
  • after(long delay) 将现有动画延迟指定毫秒后执行
  • before(Animator anim) 将现有动画插入到传入动画之前执行
  • with(Animator anim) 将现有动画和传入动画同时执行

c、通过PropertyValuesHolder实现

PropertyValuesHolder translationX = PropertyValuesHolder.ofFloat("translationX", 100, 300);PropertyValuesHolder translationY = PropertyValuesHolder.ofFloat("translationY", 200, 400);ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(iv_anim, translationX, translationY);objectAnimator.setDuration(500);objectAnimator.start();
d、通过ViewPropertyAnimator实现
ViewPropertyAnimator animate = iv_anim.animate();animate.scaleX(1.0f).scaleXBy(0.5f).scaleY(1.0f).scaleXBy(0.5f).setDuration(300).start();
多属性动画,专作用于View组件,能够实现的动画相对单一,只能实现比如缩放,透明度改变,平移、旋转等,具体函数名字:平移 translationX,translationY, X,Y,缩放 scaleX,scaleY, 旋转 rotationX, rotationY,透明度 alpha。

四、动画的监听

有时在动画开始或者结束的时候,需要做些其他操作,这是我们就需要借助于接口监听了,主要用两个回调接口。

1、AnimotorListener : 属性动画的状态监听 (开始 结束 取消 重复)

 set.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {                Log.i(TAG, "onAnimationStart: ------动画开始的时候回调 ");            }            @Override            public void onAnimationEnd(Animator animation) {                Log.i(TAG, "onAnimationStart: ------动画结束的时候回调 ");            }            @Override            public void onAnimationCancel(Animator animation) {                Log.i(TAG, "onAnimationStart: ------动画取消的时候回调 ");            }            @Override            public void onAnimationRepeat(Animator animation) {                Log.i(TAG, "onAnimationStart: ------动画重复的时候回调 ");            }         });
当然,有时候我们并不需要接口中的所用方法, 有没有办法实现需要哪个实现哪个呢?办法当然是有的, Android给我们提供了这样一个抽象类 AnimatorListenerAdater(public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener,Animator.AnimatorPauseListener), 在进行接口监听的时候,创建这个抽象类的匿名对象,就可以实现需要哪个方法就重写哪个方法啦。

 set.addListener(new AnimatorListenerAdapter() {            @Override            public void onAnimationCancel(Animator animation) {                super.onAnimationCancel(animation);                            }            @Override            public void onAnimationEnd(Animator animation) {                super.onAnimationEnd(animation);            }            @Override            public void onAnimationRepeat(Animator animation) {                super.onAnimationRepeat(animation);            }            @Override            public void onAnimationStart(Animator animation) {                super.onAnimationStart(animation);            }            @Override            public void onAnimationPause(Animator animation) {                super.onAnimationPause(animation);            }            @Override            public void onAnimationResume(Animator animation) {                super.onAnimationResume(animation);            }        });

2、AnimatorUpdataListener  属性动画更新的监听  会监听整个动画的全过程, 属性动画每播放一帧动画 onAnimationUpdate()就会被调用一次。

 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                //可以手动的修改动画的值            }        });

五、使用小技巧:

在实际开发中,最好使用代码实现的方式来实现属性动画,因为:

  1. 代码实现方式简单 。
  2. 在很多情况下 属性的起始值是无法确定的,需要通过代码动态实现。

原创粉丝点击