【Android】Property Animation(属性动画)ObjectAnimator 动画类


1. Android 中的动画之Property Animation(属性动画) 1. 概述 Property Animation 的框架弥补了View Animation的一些短板,我们可以借助属性动画完成一些复杂的动画效果,做出一些酷炫的UI交互。
2. 新增属性 Property Animation故名思议就是通过动画的方式改变对象的属性了,我们首先需要了解几个API:
  • Duration:动画的持续时间,默认300ms。
  • Time interpolation:时间差值,乍一看不知道是什么,但是我说LinearInterpolatorAccelerateDecelerateInterpolator,大家一定知道是干嘛的了,定义动画的变化率。
  • Repeat count and behavior:重复次数、以及重复模式;可以定义重复多少次;重复时从头开始,还是反向。
  • Animator sets: 动画集合,你可以定义一组动画,一起执行或者顺序执行。
  • Frame refresh delay:帧刷新延迟,对于你的动画,多久刷新一次帧;默认为10ms,但最终依赖系统的当前状态;基本不用管。 相关的类
  • ObjectAnimator:动画的执行类,后面详细介绍
  • ValueAnimator:动画的执行类,后面详细介绍
  • AnimatorSet:用于控制一组动画的执行:线性,一起,每个动画的先后执行等。
  • AnimatorInflater:用户加载属性动画的xml文件
  • TypeEvaluator:类型估值,主要用于设置动画操作属性的值。
  • TimeInterpolator:时间插值,上面已经介绍。
这篇先介绍 ObjectAnimator 动画执行类。
再了解几个新加的属性:
  • translationX 和 translationY:这两个属性控制了View所处的位置,它们的值是由layout容器设置的,是相对于坐标原点(0,0左上角)的一个偏移量。
  • rotation, rotationX 和 rotationY:控制View绕着轴点(pivotX和pivotY)旋转。
  • scaleX 和 scaleY:控制View基于pivotX和pivotY的缩放。
  • pivotX 和 pivotY:旋转的轴点和缩放的基准点,默认是View的中心点。
  • x 和 y:描述了view在其父容器中的最终位置,是左上角左标和偏移量(translationX,translationY)的和。
  • aplha:透明度,1是完全不透明,0是完全透明。
3. 使用 1. XML中定义动画效果

在XML中要利用 objectAnimator 来定义我们的某个属性的效果,所以:
  • propertyName : 理论上这个属性的值可以是对象中的任何有get/set方法的属性,不过我们这里是对View来说,所以一般而言,就是上面新加的那几种新属性了。
  • duration: 持续时间
  • valueFrom 和 valueTo:属性在动画开始和结束时相对应的值,如果我们是缩放的话,就代表倍数,如果是平移(Translation)的话,那么就代表距离了。
4)repeatCount 和 repeatMode:这两个和View Animation 中是一样的,就不多说了。
在xml中定义好了之后,接下来就要在Java中调用了,如下:
//利用AnimationInflater类的loadAnimator方法来获取我们的ObjectAnimator对象 ObjectAnimator scaleXAnimator = (ObjectAnimator)AnimatorInflater.loadAnimator(this, R.animator.scalex); //利用setTarget(View)方法来设置这个动画应用的对象 scaleXAnimator.setTarget(mView); //调用其start方法触发动画效果 scaleXAnimator.start();

当动画效果开始后,我们发现它就只是在x方向上变大,Y方向并没有变化,在XML中一个ObjectAnimator只能对应于一个属性,所以下面就是Set的展现了,跟View Animation一样,set也是将几个效果给弄在一起,一次性执行也行,顺序执行也行,只要设置其ordering属性就好。
xml中:

java中调用:
AnimatorSet animatorScaleSet = (AnimatorSet)AnimatorInflater.loadAnimator(this, R.animator.scale); animatorScaleSet.setTarget(mView); animatorScaleSet.start();

2. Java中定义动画效果
Java中提供多种方式定义动画:
  • 通过创建 OjbectAnimatorAnimatorSet 对象,并设置对应的参数和属性
  • 利用 PropertyValuesHolder 或者 ViewPropertyAnimator 对象来实现(多动画简单)
1. 简单一个动画效果
//绕X轴翻转360度 ObjectAnimator.ofFloat(view, "rotationX", 0.0F, 360.0F)// .setDuration(500)// .start();

对于 ObjectAnimator
  1. 提供了ofInt、ofFloat、ofObject,这几个方法都是设置动画作用的元素、作用的属性、动画开始、结束、以及中间的任意个属性值。
    当对于属性值,只设置一个的时候,会认为当然对象该属性的值为开始(getPropName反射获取),然后设置的值为终点。如果设置两个,则一个为开始、一个为结束~~~
    动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用ObjectAnimator更新某个属性,必须得有getter(设置一个属性值的时候)和setter方法~
  2. 如果你操作对象的该属性方法里面,比如上例的setRotationX如果内部没有调用view的重绘,则你需要自己按照下面方式手动调用。
anim.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //view.postInvalidate(); //view.invalidate(); } });

2. 定义多个动画
  1. 仍然通过 ObjectAnimator 定义多个动画
ObjectAnimator anim = ObjectAnimator// .ofFloat(view, "zhy", 1.0F,0.0F)// .setDuration(500); // anim.start(); anim.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float cVal = (Float) animation.getAnimatedValue(); view.setAlpha(cVal); view.setScaleX(cVal); view.setScaleY(cVal); } });

注:把设置属性的那个字符串,随便写一个该对象没有的属性,就是不管~咱们只需要它按照时间插值和持续时间计算的那个值,我们自己手动调用
  1. 通过 Set 定义多个动画
AnimatorSet animationSet = new AnimatorSet(); animationSet.playTogether(//一起执行 ObjectAnimator.ofFloat(mView, "alpha", 1,0,1),//透明度变化 ObjectAnimator.ofFloat(mView, "translationX", 0f,400f,0f), //X平移变化 ObjectAnimator.ofFloat(mView, "rotation", 0,180,360)//翻转变化 ); animationSet.setDuration(1000); animationSet.addListener(new AnimatorListener() {//动画监听 @Override public void onAnimationStart(Animator arg0) {} @Override public void onAnimationRepeat(Animator arg0) {} @Override public void onAnimationEnd(Animator arg0) {} @Override public void onAnimationCancel(Animator arg0) {} }); animationSet.start();

1)通过ObjectAnimator的工厂方法创建多个ObjectAnimator:
  • target:动画效果的实施对象。
  • propertyName:对应的属性,如alpha,translationX等等
  • values:这是一组值,就是由什么值变动到另外一个什么值
可以从源码看到 ObjectAnimator 方法接收的参数类型:
* @param target The object whose property is to be animated. This object should * have a public method on it called setName(), where name is * the value of the propertyName parameter. * @param propertyName The name of the property being animated. * @param values A set of values that the animation will animate between over time. * @return An ObjectAnimator object that is set up to animate between the given values. */ public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) { ObjectAnimator anim = new ObjectAnimator(target, propertyName); anim.setFloatValues(values); return anim; }

2)然后通过 AnimatorSet的playTogether方法或者playAfter, playBefore等方法将其加入到set中。
3)给set设置相对应的如duration之类的属性
【【Android】Property Animation(属性动画)ObjectAnimator 动画类】4)我们还能够给Animator添加一个Listener,让它能够对Animator的几个关键点进行响应,分别是开始,结束,重复,取消时的响应函数,在这里有一点要注意的就是:
  • 如果添加的是 AnimatorListener,则其四个函数都要实现
  • 我们也可以添加 AnimatorListenerAdapter,它是以AnimatorListener的封装,实现了上面的几个空方法,我们只需要实现我们想要的方法就好了,比如:
new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animator){ final Button button = (Button) findViewById(R.id.buttonViewPropAnimator); button.animate().alpha(1).translationX(0f).start(); } })

4)执行start方法开始动画。
3. 通过 PropertyValuesHolder 实现动画 除了Set,我们还可以利用 PropertyValuesHolderViewPropertyAnimator 对象来实现,具体做法如下:
PropertyValuesHolder
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("translationX",0f,300f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("translationY",0f,300f); ObjectAnimator translateAnimator = ObjectAnimator.ofPropertyValuesHolder(mView, pvhX, pvhY); translateAnimator.setDuration(2000); translateAnimator.start();

1)我们可以通过 PropertyValuesHolder 类的工厂方法 ofInt , ofFloat 等方法,让它能够Hold住对应 property 的 value 。
2)在利用 ObjectAnimatorofPropertyValuesHolder 方法时,再将我们上面定义的 propertyValuesHolder 给传进去,定义出一个 objectAnimator
3)设置 objectAnimator 对应的属性,调用其 start 方法就行。
4. 通过 ViewPropertyAnimator 实现动画
mView.animate().translationX(100f).alpha(0).setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animator){ final Button button = (Button) findViewById(R.id.buttonViewPropAnimator); button.animate().alpha(1).translationX(0f).start(); } }).start();

4.参考资料
  • http://blog.csdn.net/linmiansheng/article/details/18676845


作者:Rysinal
链接:https://www.jianshu.com/p/df26683d5f53
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    推荐阅读