Android Property Animation 属性动画

效果图:
 

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 接口的实现类 见下表:


 

    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

 

 
  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

 
    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);  

 

转载至:http://blog.csdn.net/jjwwmlp456/article/details/38518657

posted @ 2017-03-22 18:07  猴子1  阅读(345)  评论(0编辑  收藏  举报