Android-属性动画原理总结

Android属性动画允许开发者随着时间的流逝改变对象的属性。

我们用一个小案例看下它是如何工作的。

下面是官方文档提供的一张原理图:

从图中可以看到ValueAnimator类封装了:

一个TimeInerpolator,

一个TypeEvaluator,

动画执行的时间duration,

属性的起始值startPropertyValue,属性终止值endPropertyValue。

当我们使用属性动画就需要提供这些信息,可以是系统提供的,我们也可以自己实现,那么当一个ValueAnimator设置了这些属性,它门是如何协同工作的呢?

(勿喷。。。)

首先系统根据已经流失的时间和持续时间计算出一个elapsed fraction,将它传递给时间插值器的getInterpolation(float input)方法,该方法对输入值进行映射到0-1之间的interpolated fraction,接着该值被传递给Evaluator的evaluate(float fraction, Point start, Point end)方法,又该方法返回本次计算的属性值,可以在AnimatorUpdateListener的onAnimationUpdate(ValueAnimator anition)方法的参数animation的getAnimatedValue()方法获得最新的属性,然后重新给对象设置该属性,完成对对象属性的修改。

下面举个栗子:该例子演示了一个红色的小球匀速运动的例子。

MainActivity.java

 1 public class MainActivity extends Activity {
 2 
 3 
 4     private  ImageView ivBall;
 5 
 6     @Override
 7     protected void onCreate(Bundle savedInstanceState) {
 8         super.onCreate(savedInstanceState);
 9         setContentView(R.layout.ball);
10 
11         ivBall = (ImageView) findViewById(R.id.ivBall);
12     }
13 
14     /**
15      *  对应Button的点击事件
16      * @param view
17      */
18     public void run(View view)
19     {
20         //设置自定义的TypeEvaluator,起始属性,终止属性
21         ValueAnimator valueAnimator = ValueAnimator.ofObject(new MyTypeEvaluator(), new Point(0, 0), new Point(0, 0));
22         //设置持续时间
23         valueAnimator.setDuration(2000);
24         //设置加速时间插值器
25         valueAnimator.setInterpolator(new MyInperpolator());
26         valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {    //设置监听器
27             @Override
28             public void onAnimationUpdate(ValueAnimator animation) {
29                 //将最新计算出的属性值设置给ImageView
30                 Point point = (Point) animation.getAnimatedValue();
31                 ivBall.setX(point.x);
32                 ivBall.setY(point.y);
33             }
34         });
35 
36         //开启动画
37         valueAnimator.start();
38     }
39 
40     /**
41      * 自定义时间插值器,这里实现了线性时间插值器
42      */
43     class MyInperpolator implements TimeInterpolator
44     {
45 
46         @Override
47         public float getInterpolation(float input) {
48             return input;
49         }
50     }
51 
52     /**
53      * 实现的自己的TypeEvaluator
54      */
55     class MyTypeEvaluator implements TypeEvaluator<Point> {
56 
57         @Override
58         public Point evaluate(float fraction, Point startValue, Point endValue) {
59             Point point = new Point();
60             point.x = startValue.x + fraction * 500;
61             point.y = startValue.y + fraction * 500;
62 
63             return point;
64         }
65     }
66 
67 
68     /**
69      * 保存坐标信息
70      */
71     class Point
72     {
73         float x;
74         float y;
75         public Point()
76         {}
77 
78         public Point(float x, float y) {
79             this.x = x;
80             this.y = y;
81         }
82     }
83 
84 }

布局文件:

ball.xml:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:orientation="vertical" android:layout_width="match_parent"
 4     android:layout_height="match_parent">
 5 
 6     <ImageView
 7         android:id="@+id/ivBall"
 8         android:layout_width="40dp"
 9         android:layout_height="40dp"
10         android:background="@drawable/blue_ball"/>
11 
12     <LinearLayout
13         android:layout_width="wrap_content"
14         android:layout_height="wrap_content"
15         android:layout_alignParentBottom="true">
16 
17         <Button
18             android:id="@+id/btnVertical"
19             android:layout_width="wrap_content"
20             android:layout_height="wrap_content"
21             android:text="run"
22             android:onClick="run"/>
23 
24     </LinearLayout>
25 
26 
27 </RelativeLayout>

小球的背景:

blue_ball.xml:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <shape xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:shape="oval">
 4 
 5 
 6     <solid android:color="#0000ff"></solid>
 7     <size
 8         android:width="40dp"
 9         android:height="40dp"></size>
10     <gradient
11         android:startColor="#FFFF0000"
12         android:endColor="#80FF00FF"
13         android:angle="45"/>
14     <padding android:left="7dp"
15         android:top="7dp"
16         android:right="7dp"
17         android:bottom="7dp" />
18     <corners android:radius="8dp" />
19 
20 </shape>

  

最终的效果是:

 

 

通过这个例子再结合官方文档http://developer.android.com/guide/topics/graphics/prop-animation.html#interpolators应该不难理解属性动画了。

posted @ 2015-12-26 17:33  gatsbydhn  阅读(3572)  评论(1编辑  收藏  举报