Android Property Animation 属性动画

 

目录(?)[-]

  1. Property Animation介绍 
  2. 3.0以后新增了一些View的属性
  3. ObjectAnimator 对象动画
    1. ObjectAnimator的xml实现
      1. xml定义动画
      2. 代码加载 动画xml
  4. AnimatorSet 动画集
    1. xml定义动画集
    2. 代码加载 动画集的xml
  5. PropertyValuesHolder
  6. ViewPropertyAnimator 多属性动画
  7. ValueAnimator 值动画
    1. xml定义值动画
    2. 代码加载 值动画xml
  8. Animator的监听器
    1. AnimatorListener
    2. AnimatorListenerAdapter 监听器的默认空实现
    3. AnimatorUpdateListener 动画的值更新监听器
  9. 用属性动画换背景色
  10. LayoutTransition
 
效果图:
 

Property Animation介绍: 

出生在sdk3.0,是利用了View所拥有的属性,进行一系列的操作。比如一个View有什么样的setAbc的属性,那么理论上就可以设置它。

它不仅改变View的绘制,也改变了View的属性;而Tween Animation 只改变View的绘制。

Animator为属性动画的基类

  其结构:

Animator abstract class

   ---- AnimatorSet final class 属性动画的集合,可以添加下面的值动画和对象对象在其内,可同时运行或顺序运行

   ----ValueAnimator 值动画。监听某一值的变化,进行相应的操作

      ---- ObjectAnimator final class 对象动画

ValueAnimator 值动画,它有一个子类ObjectAnimator。需要Interpolator和TypeEvaluator来计算属性值。

TimeInterpolator 时间插入器 接口,反应动画的运动速率。getInterpolation()根据一定算法,返回时间比率

   ----Interpolator interface 继承自TimeInterpolator

   Interpolator 接口的实现类 见下表:

Android Property Animation 属性动画_第1张图片

 

    xml 设置 插入器:android:interpolator="@android:anim/accelerate_decelerate_interpolator"


TypeEvaluator<T> interface 计算类型值 支持泛型

     方法:T evaluate(float fraction, T startValue, T endValue)

   就是用来计算属性值的,即可计算任意类型的值。

   fraction 表示时间的比率。

   实现类有: ArgbEvaluator ARGB颜色计算器

   FloatEvaluator float型计算器

   IntEvaluator int计算器

 

PropertyValuesHolder 属性值持有者  持有属性名、开始与结束值。

      属性设置方法:setIntValues()、setFloatValues()、setObjectValues()、setKeyframes

      它的静态的一些of方法,创建 PropertyValuesHolder 对象。 ofInt、ofFloat、ofObject、ofKeyframe

      setEvaluator(eval); //设置计算器。

 

Keyframe  表示 a time/frame-value pair. 即含有 时间比率和帧值 属性

      它的静态的一些of方法,创建 Keyframe 对象。  ofInt、ofFloat、ofObject

KeyframeSet 就是一组KeyFrame

            它的静态的一些of方法,创建 KeyframeSet 对象。  ofInt、ofFloat、ofObject、ofKeyframe


 

[plain]  view plain copy print ? 在CODE上查看代码片
 
  1. 属性动画的一些说明:  
  2. 1. ObjectAnimator 对象动画,当一个view同时拥有某一属性的getter、setter方法时,则可以使用该动画,来操作这一属性。  
  3. 2. ValueAnimator 操作的范围比较广,通过Interpolator和TypeEvaluator得到某一时间内的值;再用监听器,监听值的变化,做相应的操作。  
  4. 3. ValueAnimator 和ObjectAnimator(它是前者的子类)的静态的一些of方法,创建自身对象。  
  5.    也可以new 一个无参的对象,再设置相应的values。  
  6.    ofInt()、ofFloat()、ofObject()、ofPropertyValuesHolder()。  
  7.      这几个方法的实现也就是new 一个无参的对象,再设置相应的values。  
  8.   
  9. 4. ValueAnimator 的调用流程:  
  10.   a. 初始化ValueAnimator后,设置一个values。这时就有了一个PropertyViewHolder对象pvh。  
  11.      可以直接调用setValues设置它PVH对象;或setInt|Float|ObjectValues  
  12.      方法内部会生成一个PVH  
  13.      PVH内部维护一个KeyframeSet和TypeEvaluator。PVH根据不同的values来初始化KeyframeSet和  
  14.      TypeEvaluator实现方法中的startValue和endValue就从KeyframeSet中的Keyframe中获取  
  15.   b. 设置TypeEvaluator,传递到pvh中。  
  16.   c. 设置Interpolator。 ValueAnimator中默认的插入器为AccelerateDecelerateInterpolator  
  17.   d. ValueAnimator的animationFrame(long currentTime),当有动画应该结束时返回true,否则返回false。  
  18.      方法内,算出动画运行的时间比率fraction,再调用animateValue(float fraction)。  
  19.   e. ValueAnimator的animateValue(float fraction),调用插入器,得到一个按某一规则得到的fraction,  
  20.      再调用 pvh.calculateValue(fraction);pvh调用KeyframeSet的getValue(fraction);  
  21.      KeyframeSet内部再调用TypeEvaluator的evaluate(fraction,T startValue, T endValue)。  
  22.      startValue、endValue是通过Keyframe的getValue()来获取的。  
  23.   f. evaluate(),方法内拿到了时间比率fraction,可以自行根据一定规则,返回value T。  
  24.   g. 给ValueAnimator添加一个AnimatorUpdateListener。监听的回调方法:  
  25.       onAnimationUpdate(ValueAnimator animation) {   
  26.          T obj = (T)animation.getAnimatedValue();//取得计算器计算出的某段时间内的T值。  
  27.          // 操作 obj  
  28.      }  


 


先来一个使用自定义类型的求值计算器的ValueAnimator的例子

 

[java]  view plain copy print ? 在CODE上查看代码片
 
  1.     ValueAnimator backAnim;  
  2.     ImageView view;  
  3.   
  4.     @Override  
  5.     protected void onCreate(Bundle savedInstanceState) {  
  6.         super.onCreate(savedInstanceState);  
  7.           
  8.         setContentView(R.layout.aa);  
  9.           
  10.         view = (ImageView) findViewById(R.id.iv_img);   
  11.           
  12.         backAnim = new ValueAnimator();  
  13.         backAnim.setTarget(view);  
  14.         backAnim.setDuration(2000);  
  15.           
  16.         //类型求值<Drawable>:求出某一时间比值内的Drawable值   
  17.         TypeEvaluator<Drawable> drawableEvaluator = new TypeEvaluator<Drawable>() {  
  18.           
  19.             @Override  //fraction 当前运行的时间比上总持续时间的 比值(中间经过插入器的规则运算)  
  20.             public Drawable evaluate(float fraction, Drawable startValue,  
  21.                     Drawable endValue) {  
  22.                 System.out.println(fraction);  
  23.                 if (fraction < 0.5) {  
  24.                     return startValue;  
  25.                 } else {  
  26.                     return endValue;  
  27.                 }  
  28.             }  
  29.         };  
  30.           
  31.         //可以直接设置PVH对象;也可以先设置values,再设置TypeEvaluator  
  32. //      PropertyValuesHolder pvh = PropertyValuesHolder.ofObject("imageDrawable", drawableEvaluator,   
  33. //               getResources().getDrawable(R.drawable.ic_launcher), getResources().getDrawable(R.drawable.a1));  
  34. //      backAnim.setValues(pvh);  
  35.         backAnim.setObjectValues(getResources().getDrawable(R.drawable.ic_launcher), getResources().getDrawable(R.drawable.a2));  
  36.         backAnim.setEvaluator(drawableEvaluator);  
  37.           
  38.         backAnim.addUpdateListener(new AnimatorUpdateListener() {  
  39.               
  40.             @Override  
  41.             public void onAnimationUpdate(ValueAnimator animation) {  
  42.                 Drawable value = (Drawable) animation.getAnimatedValue();  
  43.                 view.setImageDrawable(value);  
  44.             }  
  45.         });  
  46.         backAnim.setInterpolator(new CycleInterpolator(2));  
  47.         backAnim.start();  
  48.     }  

 

3.0以后新增了一些View的属性:

1)translationX 和 translationY:这两个属性控制了View所处的位置,
     它们的值是由layout容器设置的,是相对于坐标原点(0,0左上角)的一个偏移量。

2)rotation, rotationX 和 rotationY:控制View绕着轴点(pivotX和pivotY)旋转。它的表现跟Tween Animation中的RotateAnimation不一致。

RotateAnimation 的旋转,表现为平面的旋转

     而rotationX、Y 旋转,是立体的旋转,默认是以View的中心点,做rotation(x,y)过中心点的直线,面向该直线进行翻转
3)scaleX 和 scaleY:控制View基于pivotX和pivotY的缩放。
4)pivotX 和 pivotY:旋转的轴点和缩放的基准点,默认是View的中心点。
5)x 和 y:描述了view在其父容器中的最终位置,是左上角坐标和偏移量(translationX,translationY)的和。
6)aplha:透明度,1是完全不透明,0是完全透明。

以上这些属性与Tween Animation的动画属性值差不多

 

ObjectAnimator 对象动画

该动画,一次只能表示一个动作属性。

ObjectAnimator的xml实现

xml定义动画

res/animator/scale_object_animator.xml

 

[html]  view plain copy print ? 在CODE上查看代码片
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:duration="2000"  
  4.     android:propertyName="scaleX"  
  5.     android:repeatCount="1"  
  6.     android:repeatMode="reverse"  
  7.     android:valueFrom="1.0"  
  8.     android:valueTo="2.0" >  
  9.   
  10. </objectAnimator>  

代码加载 动画xml

 

[java]  view plain copy print ? 在CODE上查看代码片
 
  1. imageview_scale.setBackground(getResources().getDrawable(R.drawable.a11));  
  2.         ObjectAnimator scaleAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.scale_object_animator);  
  3.         scaleAnimator.setTarget(imageview_scale);//设置动画作用的目标对象  
  4.         scaleAnimator.setDuration(1000);  
  5.         scaleAnimator.setRepeatCount(50);  
  6.         scaleAnimator.start();  

AnimatorSet 动画集

由ObjectAnimator 和 ValueAnimator 组成,对应的xml中的写法 类似为 <set> <objectAnimator /> ... <animator />... </set>

 

xml定义动画集

 

res/animator/set_rotate_scale.xml

 

[html]  view plain copy print ? 在CODE上查看代码片
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android"   
  3.     android:ordering="together">  
  4.   
  5.     <!-- android:ordering  together表示同时运行动画,  sequentially 表示按顺序执行以下动画 -->  
  6.     <set>  
  7.         <objectAnimator  
  8.             android:propertyName="rotationX"  
  9.             android:repeatCount="50"  
  10.             android:repeatMode="reverse"  
  11.             android:valueFrom="0"  
  12.             android:valueTo="20" />  
  13.         <objectAnimator  
  14.             android:propertyName="rotationY"  
  15.             android:repeatCount="50"  
  16.             android:repeatMode="reverse"  
  17.             android:valueFrom="0"  
  18.             android:valueTo="45"  
  19.             android:valueType="floatType" />  
  20.     </set>  
  21.     <set>  
  22.         <objectAnimator  
  23.             android:propertyName="scaleX"  
  24.             android:repeatCount="50"  
  25.             android:repeatMode="reverse"  
  26.             android:valueFrom="1.0"  
  27.             android:valueTo="2.0" >  
  28.         </objectAnimator>  
  29.         <objectAnimator  
  30.             android:propertyName="scaleY"  
  31.             android:repeatCount="50"  
  32.             android:repeatMode="reverse"  
  33.             android:valueFrom="1.0"  
  34.             android:valueTo="2.0" >  
  35.         </objectAnimator>  
  36.     </set>  
  37.   
  38. </set>  

 

 
  

代码加载 动画集的xml

[java]  view plain copy print ? 在CODE上查看代码片
 
  1. imageview_rotate.setBackground(getResources().getDrawable(R.drawable.a11));  
  2.         AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.set_rotate_scale);  
  3.         animatorSet.setTarget(imageview_rotate);  
  4.         animatorSet.setDuration(1000);  
  5.         animatorSet.setInterpolator(new BounceInterpolator());//设置end时的弹跳插入器  
  6.         animatorSet.start();  

PropertyValuesHolder

[java]  view plain copy print ? 在CODE上查看代码片
 
  1. //使用PropertyValuesHolder 构造 Animator   组合成类似set的效果  
  2.         PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("scaleX",0f,2.5f);  
  3.         PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleY",0f,3f);       
  4.         ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageview, pvhX,pvhY);  
  5.         animator.setDuration(2000);  
  6.         animator.start();  

APIDemo中的MultiPropertyAnimation示例:

 

[java]  view plain copy print ? 在CODE上查看代码片
 
  1. // ============================================================  
  2.               // 第四个小球:利用关键帧实现曲线运动  
  3.               ball = balls.get(3);  
  4.               // 属性1:Y坐标运动:下落  
  5.               pvhY = PropertyValuesHolder.ofFloat("y", ball.getY(),  
  6.                       getHeight() - BALL_SIZE);  
  7.               float ballX = ball.getX();  
  8.               // 三个关键帧  
  9.               Keyframe kf0 = Keyframe.ofFloat(0f, ballX); //参数为 time/value, 即时间点和指定值。还有这些构造ofInt()、ofObject()  
  10.               Keyframe kf1 = Keyframe.ofFloat(.5f, ballX + 100f);  
  11.               Keyframe kf2 = Keyframe.ofFloat(1f, ballX + 50f);  
  12.               // 属性2:X坐标运动:曲折  
  13.               // 用三个关键帧构造PropertyValuesHolder对象  
  14.               PropertyValuesHolder pvhX = PropertyValuesHolder.ofKeyframe(  
  15.                       "x", kf0, kf1, kf2);  
  16.   
  17.               // 再用两个PropertyValuesHolder对象构造一个ObjectAnimator对象。<span style="color:#ff6666;">一个holder持有一个属性</span>  
  18.               ObjectAnimator yxBouncer = ObjectAnimator  
  19.                       .ofPropertyValuesHolder(ball, pvhY, pvhX).setDuration(  
  20.                               DURATION / 2);  
  21.               yxBouncer.setRepeatCount(1);  
  22.               yxBouncer.setRepeatMode(ValueAnimator.REVERSE);  


 

ViewPropertyAnimator 多属性动画

通过view.animate()来获取ViewPropertyAnimator。该类,能直接操作多个属性的动画。

[java]  view plain copy print ? 在CODE上查看代码片
 
  1. imageview.setBackground(getResources().getDrawable(R.drawable.a11));  
  2.         ViewPropertyAnimator animate = imageview.animate();//该对象没有setRepeat的方法  
  3.         //通过一些动画属性来设置 组合成类似set的效果  
  4.         animate.alpha(0);  
  5.         animate.rotationX(50);  
  6.         animate.translationXBy(500);  
  7.         animate.scaleX(1.5f);  
  8.         animate.scaleY(1.5f);  
  9.         animate.setInterpolator(new BounceInterpolator());  
  10.         animate.setDuration(2000);  
  11.         animate.start();  

ValueAnimator 值动画

ValueAnimator代码和xml设置中 没有setPropertyName 因为不是操作对象,只是根据value进行某种动作
需要加监听器,监听值的变化 做相应的处理

 

xml定义值动画

 

 

[html]  view plain copy print ? 在CODE上查看代码片
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <animator xmlns:android="http://schemas.android.com/apk/res/android"   
  3.     android:interpolator="@android:anim/accelerate_interpolator"  
  4.     android:duration="10000"  
  5.     android:startOffset="1000"  
  6.     android:repeatCount="infinite"  
  7.     android:repeatMode="restart"  
  8.     android:valueFrom="1"  
  9.     android:valueTo="100"  
  10.     android:valueType="intType">  
  11.   
  12. </animator>  

代码加载 值动画xml

[java]  view plain copy print ? 在CODE上查看代码片
 
  1. ValueAnimator valueAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.animator);  
  2.         valueAnimator.setTarget(tv_num);  
  3.         valueAnimator.setEvaluator(new TypeEvaluator<Integer>() {  
  4.   
  5.             @Override   
  6.             public Integer evaluate(float fraction, Integer startValue, Integer endValue) {  
  7.                 System.out.println("时间比率,fraction:" + fraction);  
  8.                 System.out.println("结果值:" + (int)((startValue + fraction * (endValue - startValue)) / 10 * 10));  
  9.                 return (int)((startValue + fraction * (endValue - startValue)) / 10 * 10);  
  10.             }  
  11.         });  
  12.         valueAnimator.addUpdateListener(new AnimatorUpdateListener() {  
  13.               
  14.             @Override  
  15.             public void onAnimationUpdate(ValueAnimator animation) {  
  16.                 //在onAnimationUpdate中 该值返回第一个动画的 当前帧的evaluate 值  
  17.                 System.out.println("animation.getAnimatedValue()==" + animation.getAnimatedValue());  
  18.                 tv_num.setText(animation.getAnimatedValue() + "");  
  19.             }  
  20.         });  
  21. //      valueAnimator.setInterpolator(new LinearInterpolator());  
  22.         valueAnimator.start();  

Animator的监听器

AnimatorListener

 

 

[java]  view plain copy print ? 在CODE上查看代码片
 
  1. new AnimatorListener() {//有以下四个抽象方法  
  2.               
  3.             @Override  
  4.             public void onAnimationStart(Animator animation) {  
  5.                   
  6.             }  
  7.               
  8.             @Override  
  9.             public void onAnimationRepeat(Animator animation) {  
  10.                   
  11.             }  
  12.               
  13.             @Override  
  14.             public void onAnimationEnd(Animator animation) {  
  15.                   
  16.             }  
  17.               
  18.             @Override  
  19.             public void onAnimationCancel(Animator animation) {  
  20.                   
  21.             }  
  22.         }  

 

AnimatorListenerAdapter 监听器的默认空实现

[java]  view plain copy print ? 在CODE上查看代码片
 
  1. new AnimatorListenerAdapter() {//空实现了AnimatorListener,有以下6个方法(4个必须实现的方法和2个重写的方法)  
  2.   
  3.             @Override  
  4.             public void onAnimationCancel(Animator animation) {  
  5.                 super.onAnimationCancel(animation);  
  6.             }  
  7.   
  8.             @Override  
  9.             public void onAnimationEnd(Animator animation) {  
  10.                 super.onAnimationEnd(animation);  
  11.             }  
  12.   
  13.             @Override  
  14.             public void onAnimationRepeat(Animator animation) {  
  15.                 super.onAnimationRepeat(animation);  
  16.             }  
  17.   
  18.             @Override  
  19.             public void onAnimationStart(Animator animation) {  
  20.                 super.onAnimationStart(animation);  
  21.             }  
  22.   
  23.             @Override  
  24.             public void onAnimationPause(Animator animation) {  
  25.                 super.onAnimationPause(animation);  
  26.             }  
  27.   
  28.             @Override  
  29.             public void onAnimationResume(Animator animation) {  
  30.                 super.onAnimationResume(animation);  
  31.             }  
  32.               
  33.         }  

AnimatorUpdateListener 动画的值更新监听器

 

[java]  view plain copy print ? 在CODE上查看代码片
 
  1. new AnimatorUpdateListener() {  
  2.               
  3.             @Override  
  4.             public void onAnimationUpdate(ValueAnimator animation) {  
  5.                 //在onAnimationUpdate中 该值返回第一个动画的 当前帧的evaluate 值  
  6.                 System.out.println("animation.getAnimatedValue()==" + animation.getAnimatedValue());  
  7.             }  
  8. }  

一些操作函数:

    animator.pause();  animator.resume(); animator.reverse(); animator.end(); animator.cancel();

 

    animator.start(); animator.isStarted(); animator.isPaused(); animator.isRunning();

 

用属性动画换背景色

详见ApiDemo要下的 BouncingBalls.java

 

[java]  view plain copy print ? 在CODE上查看代码片
 
  1. private static final int RED = 0xffFF8080;  
  2. private static final int BLUE = 0xff8080FF;  
  3. private static final int CYAN = 0xff80ffff;  
  4. private static final int GREEN = 0xff80ff80;  
  5.   
  6. {  
  7.     //动画 变色    
  8.     ObjectAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", CYAN, BLUE, RED);  
  9.     colorAnim.setTarget(ll_animation);  
  10.     colorAnim.setEvaluator(new ArgbEvaluator());  
  11.     colorAnim.setRepeatCount(ValueAnimator.INFINITE);  
  12.     colorAnim.setRepeatMode(ValueAnimator.REVERSE);  
  13.     colorAnim.setDuration(3000);  
  14.     colorAnim.start();  
  15. }  

LayoutTransition

[java]  view plain copy print ? 在CODE上查看代码片
 
  1. /* 
  2.          * ViewGroup中使用LayoutTransition 进行 监听布局的改变,而创建动画 
  3.          * LayoutTransition.APPEARING 新增出现时 
  4.          *                  CHANGE_APPEARING  
  5.          *                  CHANGE_DISAPPEARING 子view消失时 
  6.          *                  CHANGING 
  7.          * ViewGroup布局中:android:animateLayoutChanges="true"  使用的默认的LayoutTransition制作动画 
  8.          */  
  9.         LayoutTransition layoutTransition = new LayoutTransition();  
  10.         layoutTransition.setDuration(5000);  
  11.         layoutTransition.setAnimator(LayoutTransition.APPEARING, scaleAnimator);  
  12.         ll_animation.setLayoutTransition(layoutTransition);  
  13.           
  14.         final TextView tv = new TextView(this);  
  15.         tv.setWidth(100);  
  16.         tv.setHeight(100);  
  17.         tv.setText("中华人民共和国");  
  18.         ll_animation.addView(tv);//对应type = APPEARING  
  19.           
  20.         ll_animation.postDelayed(new Runnable() {  
  21.               
  22.             @Override  
  23.             public void run() {  
  24.                 ll_animation.removeView(tv);  
  25.             }  
  26.         }, 2000);  

你可能感兴趣的:(Android Property Animation 属性动画)