zoukankan      html  css  js  c++  java
  • 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应该不难理解属性动画了。

  • 相关阅读:
    算法面试题总结
    面试题目整理
    九月百度,迅雷,华为,阿里巴巴,最新校招笔试面试十题
    ubuntu 环境变量配置
    VM 共享设置
    五大常用算法之五:分支限界法
    五大常用算法之四:回溯法
    Python之路【第十六篇】Django基础
    Python之路【第十五篇】WEB框架
    Python之路【第十四篇】前端补充回顾
  • 原文地址:https://www.cnblogs.com/gatsbydhn/p/5078473.html
Copyright © 2011-2022 走看看