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應該不難理解屬性動畫了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM