博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
属性动画总结(Property Animation)
阅读量:6415 次
发布时间:2019-06-23

本文共 7772 字,大约阅读时间需要 25 分钟。

hot3.png

一、概述

  属性动画可以作用在View的属性上,对属性进行修改,而且不要求对应的属性一定是有显示效果的。

 

二、属性动画的实现方式

  1、基础的类Animator

  Animator是一个抽象类,是属性动画的基础类。不直接使用该类。

 

  2、ObjectAnimator,继承自ValueAnimator

  使用起来比较方便的是ObjectAnimator,可以使用ObjectAnimator直接指定需要修改的view,要修改的属性,值的变化范围。  

  ObjectAnimator.ofFloat(view, "rotationX", 0.0F, 360.0F)         .setDuration(500)         .start();

  通过上面的代码,就可以让View动起来,十分方便。ObjectAnimator不止有ofFloat方法,还有ofInt,ofArgb等方法,都可以比较方便的绑定View和对应的属性。

 

  3、ValueAnimator,继承自Animator

  是ObjectAnimator的父类。它不能绑定到具体的属性上,而且没有重写setTarget方法,而Animator中的setTarget方法为空。所以ValueAnimator实际上没有设置View和对应的属性。这就要求使用者自己获取变化的值,并将值赋给具体View对象的属性。

  当然,ValueAnimator其实也十分方便,只需要加上监控事件,在监控的事件中处理相关赋值就可以了。

复制代码

     ValueAnimator animator = ValueAnimator.ofFloat(0, mScreenHeight                  - mBlueBall.getHeight());          animator.setDuration(1000).start();          animator.addUpdateListener(new AnimatorUpdateListener()          {              @Override              public void onAnimationUpdate(ValueAnimator animation)              {                  mBlueBall.setTranslationY((Float) animation.getAnimatedValue());              }          });

复制代码

  可以为ValueAnimator设置重复的次数(setRepeatCount)和重复的模式(setRepeatMode),重复的模式可以是(RESTART)或者(REVERSE)。

 

  4、AnimatorSet,继承自Animator

  如果想要在View上实现多个动画效果,可以借助于AnimatorSet。如果多个动画同时执行,可以使用AnimatorSet.playTogether方法;如果多个动画按顺序执行,可以使用AnimatorSet.playSequentially方法;如果多个动画没有统一的执行顺序,AnimatorSet提供了play,with,before,after来设置多个动画执行的顺序。

  

  5、PropertyValuesHolder

  PropertyValuesHolder是属性(Property)和值(Value)的对应。ValueAnimator和ObjectAnimator对应的ofInt、ofFloat等都是借助于PropertyValuesHolder来实现的。

  对于在View上实现多个动画效果的要求,也可以使用PropertyValuesHolder来实现。ValueAnimator和ObjectAnimator都提供了方法,可以传入多个PropertyValuesHolder对象,来实现在多个属性上同时产生动画效果的要求。  

     PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f, 0f, 1f);        PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);        PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("rotationX", 0f, 180, 360f);        ObjectAnimator.ofPropertyValuesHolder(iv_src, pvhX, pvhY, pvhZ).setDuration(2000).start();

 

  6、xml

  也可以使用xml文件来定义属性函数,然后在程序中使用AnimatorInflater.loadAnimator方法加载属性动画。xml中,可以使用<set>、<objectAnimator>。

 

三、监听类

  1、AnimatorUpdateListener

  在ValueAnimator的时候提到了这个监听类。它在计算的值发生改变的时候回调,只包含一个方法。是ValueAnimator中定义的内部类。

复制代码

/**     * Implementors of this interface can add themselves as update listeners     * to an ValueAnimator instance to receive callbacks on every animation     * frame, after the current frame's values have been calculated for that     * ValueAnimator.     */    public static interface AnimatorUpdateListener {        /**         * 

Notifies the occurrence of another frame of the animation.

* * @param animation The animation which was repeated. */ void onAnimationUpdate(ValueAnimator animation); }

复制代码

 

  2、AnimatorListener

  在属性动画的开始、结束、取消、重复的时候回调,在Animator中定义的内部类。

复制代码

/**     * 

An animation listener receives notifications from an animation. * Notifications indicate animation related events, such as the end or the * repetition of the animation.

*/ public static interface AnimatorListener { /** *

Notifies the start of the animation.

* * @param animation The started animation. */ void onAnimationStart(Animator animation); /** *

Notifies the end of the animation. This callback is not invoked * for animations with repeat count set to INFINITE.

* * @param animation The animation which reached its end. */ void onAnimationEnd(Animator animation); /** *

Notifies the cancellation of the animation. This callback is not invoked * for animations with repeat count set to INFINITE.

* * @param animation The animation which was canceled. */ void onAnimationCancel(Animator animation); /** *

Notifies the repetition of the animation.

* * @param animation The animation which was repeated. */ void onAnimationRepeat(Animator animation); }

复制代码

 

  3、AnimatorPauseListener

  在属性动画暂停、继续执行的时候回调,在Animator类中定义的内部类。

复制代码

/**     * A pause listener receives notifications from an animation when the     * animation is {@link #pause() paused} or {@link #resume() resumed}.     *     * @see #addPauseListener(AnimatorPauseListener)     */    public static interface AnimatorPauseListener {        /**         * 

Notifies that the animation was paused.

* * @param animation The animaton being paused. * @see #pause() */ void onAnimationPause(Animator animation); /** *

Notifies that the animation was resumed, after being * previously paused.

* * @param animation The animation being resumed. * @see #resume() */ void onAnimationResume(Animator animation); }

复制代码

 

  AnimatorListener和AnimatorPauseListener有一个共同的实现类——AnimatorListenerAdapter 。这个类实现了两个接口的所有方法,但是它是一个抽象类,它实现的方法都是空方法,所以没有任何意义。只是如果我们想继承AnimatorListener或者AnimatorPauseListener,但是不想实现所有方法时,使用AnimatorListenerAdapter会很方便。

 

四、属性动画的其他功能

  1、Interpolator

  Interpolator表示变化率。它可以把输入的匀速的变化转换成加速、减速等不同的变化率。Android提供了以下Interpolator的实现类:    

  •   AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
  •   AccelerateInterpolator  在动画开始的地方速率改变比较慢,然后开始加速
  •   AnticipateInterpolator 开始的时候向后然后向前甩
  •   AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
  •   BounceInterpolator   动画结束的时候弹起
  •   CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
  •   DecelerateInterpolator 在动画开始的地方快然后慢
  •   LinearInterpolator   以常量速率改变
  •   OvershootInterpolator    向前甩一定值后再回到原来位置

  如果上面的实现类仍然不能满足具体的场景,可以自己实现Interpolator,只需要实现float getInterpolation(float input)方法就可以了。

  Animator提供setInterpolator(TimeInterpolator)方法用于设置变化率。而实际上Interpolator接口就直接继承了TimeInterpolator接口,并且没有新增加任何方法或常量等信息。所以Interpolator和TimeInterpolator完全等价。

  Animation(补间动画)及其子类,包含方法setInterpolator(Interpolator),所以Android提供的这些变化率实现类同样适用于补间动画。

 

  2、TypeEvaluator

  类型估值,用于计算并返回属性值。

  TypeEvaluator的定义如下:

public interface TypeEvaluator
{ public T evaluate(float fraction, T startValue, T endValue);}

 

  3、我个人的理解是这样,首先通过Interpolator将匀速的变化变成自己想要的变化率,然后再使用TypeEvaluator将这个变化率转换成自己想要的数据(可能是位置对应的Point,或者其他结构的数据(比如,把位置信息和alpha值一起组装成一个类,表示透明度和位置有明确的相关性),甚至可以是按照某种规则实现的boolean也未尝不可,如此等等的逻辑可以在这里实现)。

  那现在有一个问题,既然Interpolator和TypeEvaluator都是计算值,为什么不把二者合在一起?个人认为可以这样理解,这包含了一种解耦的思想。Interpolator表示速率的变化,是匀速的,是越来越快的,还是先快后慢的等等;而TypeEvaluator则用于计算View的实际状态。两者分开之后,不但在开始设计的时候降低了复杂度,而且可以达到更好的扩展性。如果想要调整变化率,修改Interpolator,如果想要修改View的显示规则,则修改TypeEvaluator。  

复制代码

ValueAnimator valueAnimator = new ValueAnimator();          valueAnimator.setDuration(3000);          valueAnimator.setObjectValues(new PointF(0, 0));          valueAnimator.setInterpolator(new LinearInterpolator());          valueAnimator.setEvaluator(new TypeEvaluator
() { // fraction = t / duration @Override public PointF evaluate(float fraction, PointF startValue, PointF endValue) { Log.e(TAG, fraction * 3 + ""); // x方向200px/s ,则y方向0.5 * 10 * t PointF point = new PointF(); point.x = 200 * fraction * 3; point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3); return point; } }); valueAnimator.start(); valueAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { PointF point = (PointF) animation.getAnimatedValue(); mBlueBall.setX(point.x); mBlueBall.setY(point.y); } });

复制代码

 

转载于:https://my.oschina.net/JiangTun/blog/1491702

你可能感兴趣的文章
最新Sublime Text 2 激活 汉化
查看>>
基础数据类型之字典
查看>>
第七次作业
查看>>
Oracle中NVARCHAR2与VARCHAR2的区别
查看>>
php debug
查看>>
Ubuntu构建LVS+Keepalived高可用负载均衡集群【生产环境部署】
查看>>
lvm实现快速备份文件及数据库,lvm快照原理
查看>>
设计模式之Factory Method(工厂方法)
查看>>
10K入职linux运维岗位小伙伴感谢信及面试经历分享
查看>>
zookeeper入门之Curator的使用之几种监听器的使用
查看>>
[转]Reporting Service部署之访问权限
查看>>
innerxml and outerxml
查看>>
validform校验框架不显示错误提示
查看>>
flink 获取上传的Jar源码
查看>>
Spring Data JPA Batch Insertion
查看>>
UEditor自动调节宽度
查看>>
JAVA做验证码图片(转自CSDN)
查看>>
Delphi TServerSocket,TClientSocket实现传送文件代码
查看>>
JS无聊之作
查看>>
Mac上搭建ELK
查看>>