Android 属性动画原理与DataBinding
Android属性动画原理与DataBinding
看到这个标题的时候你可能会有疑问,属性动画和DataBinding之间有什么关系?我个人理解的是:它们内部的实现思想有相似之处。这篇文章主要对Android属性动画的知识通过文字进行整理记录,内容参考于《Android开发艺术探索》,在最后会给出我如此理解属性动画和DataBinding的原因。
Android动画概述:
Android的动画可以分为三种:View动画、帧动画和属性动画,View动画通过对场景里的对象不断做图像变化(平移、缩放、旋转、透明度)从而产生动画效果,View动画支持自定义。帧动画通过顺序播放一系列图像产生动画效果,可以简单理解为图片切换动画,图片过大会导致OOM。属性动画通过动态的改变对象的属性从而达到动画效果,属性动画为API11的新特性,在低版本需要通过兼容库来使用它。
属性动画:
属性动画可以对任意对象的属性进行动画而不仅仅是View,在一个时间间隔内可以完成对象从一个属性值到另一个属性值的改变。因此属性动画几乎是无所不能的,只要对象有这个属性,它都能实现动画效果。、
使用:
属性动画中有ValueAnimator、ObjectAnimator和AnimatorSet等概念,其中ObjectAnimator继承自ValueAnimator,用来是实现一个属性动画,AnimatorSet是动画集合,可以定义一组动画,它们使用起来是及其简单的,在此不再举例。属性动画除了通过代码实现以外,同View动画一样,也可以通过XML来定义,属性动画需要定义在res/animator目录下,其中的set、objectAnimator和animator标签分别对应AnimatorSet、ObjectAnimator和ValueAnimator。尽管属性动画可以通过XML来实现,但在实际开发中往往会采用代码来实现,因为很多时候一个属性的起始值是无法提前确定的。
插值器和估值器:
TimeInterpolator译为时间插值器,它的作用是根据时间流逝的百分比来计算出当前属性值改变的百分比,系统预置的有LinearInterpolator(线性插值器:匀速动画)、AccelerateDecelerateInterpolator(加速减速插值器:动画两头慢中间快)和DecelerateInterpolator(减速插值器:动画越来越慢)等。
TypeEvaluator译为类型估值算法,也叫估值器,它的作用是根据当前属性改变的百分比来计算改变后的属性值,系统预置的有IntEvaluator(针对整型属性)、FloatEvaluator(针对浮点型属性)和ArgbEvaluator(针对Color属性)。属性动画中的插值器(Interpolator)和估值器(TypeEvaluator)很重要,它们是实现非匀速动画的重要手段。
属性动画的监听器:
属性动画提供了监听器来监听动画的播放过程,主要有AnimatorUpdateListener和AnimatorListener。AnimatorListener可以监听动画的开始、结束、取消以及重复播放,同时为了方便开发,系统还提供了AnimatorListenerAdapter这个类,他是AnimatorListener的适配器类,可以有选择的实现这四个监听方法。AnimatorUpdateListener比较特殊,他会监听整个动画过程,动画是由许多帧组成的,每播放一帧对应监听方法就会被调用一次。
对任意属性做动画:
属性动画可以对任意属性添加动画效果,假如我们要给一个button加一个动画,让这个button的宽度增加100px,我们可能会这样写:
@Override publicvoidonClick(Viewv){ ObjectAnimator.ofInt(v,"width",100).setDuration(1000).start(); }
但是当点击按钮后并没有效果,不是说好的可以对任意属性实现动画嘛,其实没效果是对的,下面分析属性动画的原理:属性动画要求动画作用的对象提供该属性的get和set方法,属性动画根据外界传递的该属性的初始值和最终值,以动画的效果多次去调用set方法,每次传递给set方法的值都不一样,确切的来说是随着时间的推移,所传递的值越来越接近最终值。总结一下,我们对object的属性abc做动画,如果想让动画生效,要同时满足以下两个条件:
1.object必须提供setAbc方法,如果动画的时候没有传递初始值,那么还要提供getAbc方法,因为系统要去取abc属性的初始值(若这条不满足,程序直接Crash)
2.object的setAbc对属性abc所做的改变必须能够通过某种方法反映出来,比如会带来UI的改变之类的(如果这条不满足,动画无效果但不会Crash)
这跟DataBinding中的思想是一样的,这里的object对应于DataBinding中的ViewModel,ViewModel的成员变量set方法中需要提醒DataBinding去更新view的内容,如下:
publicvoidsetName(Stringname){ this.name=name; notifyPropertyChanged(BR.name); }
针对以上问题,官方文档告诉我们有3种解决方法:
- 给你的对象加上get和set方法,如果有权限的话
- 用一个类来包装原始对象,间接为其提供get和set方法
- 采用ValueAnimator,监听动画过程,自己实现属性的改变
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!