属性动画和硬件加速
属性动画
ViewPropertyAnimator
使⽤View.animate()创建对象,以及使⽤ViewPropertyAnimator.translationX()等⽅法来设置动画;
可以连续调⽤来设置多个动画;
可以⽤setDuration()来设置持续时间;
可以⽤setStartDelay()来设置开始延时;
以及其他⼀些便捷⽅法。
ObjectAnimator
使⽤ObjectAnimator.ofXxx()来创建对象,以及使⽤ObjectAnimator.start()来主动启动动画。它的优势在于,可以为⾃定义属性设置动画。
1 | ObjectAnimatoranimator=ObjectAnimator.ofObject(view, "radius", Utils.dp2px(200)); |
另外,⾃定义属性需要设置 getter 和 setter ⽅法,并且 setter ⽅法⾥需要调⽤invalidate()来触发重绘:
1 | publicfloatgetRadius() { |
可以使⽤setDuration()来设置持续时间;
可以⽤setStartDelay()来设置开始延时;
以及其他⼀些便捷⽅法。
Interpolator
插值器,⽤于设置时间完成度到动画完成度的计算公式,直⽩地说即设置动画的速度曲线,通过setInterpolator(Interpolator)⽅法来设置。
常⽤的有AccelerateDecelerateInterpolator AccelerateInterpolatorDecelerateInterpolator LinearInterpolator。
PropertyValuesHolder
⽤于设置更加详细的动画,例如多个属性应⽤于同⼀个对象:
1 | PropertyValuesHolderholder1=PropertyValuesHolder.ofFloat("radius", Utils.dp2px(200)); |
或者,配合使⽤Keyframe,对⼀个属性分多个段:
1 | Keyframekeyframe1=Keyframe.ofFloat(0, Utils.dpToPixel(100)); |
AnimatorSet
将多个 Animator 合并在⼀起使⽤,先后顺序或并列顺序都可以:
1 | AnimatorSetanimatorSet=newAnimatorSet(); |
TypeEvaluator
⽤于设置动画完成度到属性具体值的计算公式。默认的ofInt() ofFloat()已经有了⾃带的IntEvaluatorFloatEvaluator,但有的时候需要⾃⼰设置 Evaluator。例如,对于颜⾊,需要为 int 类型的颜⾊设置 ArgbEvaluator,⽽不是让它们使⽤ IntEvaluator:
1 | animator.setEvaluator(newArgbEvaluator()); |
如果你对 ArgbEvaluator 的效果不满意,也可以⾃⼰写⼀个HsvEvaluator:
1 | publicclassHsvEvaluatorimplementsTypeEvaluator<Integer> { |
另外,对于不⽀持的类型,也可以使⽤ofObject()来在创建 Animator 的同时就设置上Evaluator,⽐如NameEvaluator:
1 | publicclassNameEvaluatorimplementsTypeEvaluator<String> { |
Listeners
和 View 的点击、⻓按监听器⼀样,Animator 也可以使⽤setXxxListener() addXxxListener()来设置监听器。
ValueAnimator
这是最基本的 Animator,它不和具体的某个对象联动,⽽是直接对两个数值进⾏渐变计算。使⽤很少。
硬件加速
硬件加速是什么
- 使⽤ CPU 绘制到 Bitmap,然后把 Bitmap 贴到屏幕,就是软件绘制;
- 使⽤ CPU 把绘制内容转换成 GPU 操作,交给 GPU,由 GPU 负责真正的绘制,就叫硬件绘制;
- 使⽤ GPU 绘制就叫做硬件加速
怎么就加速了?
- GPU 分摊了⼯作
- GPU 绘制简单图形(例如⽅形、圆形、直线)在硬件设计上具有先天优势,会更快
- 流程得到优化(重绘流程涉及的内容更少)
硬件加速的缺陷:
兼容性。由于使⽤ GPU 的绘制(暂时)⽆法完成某些绘制,因此对于⼀些特定的 API,需要关闭硬件
加速来转回到使⽤ CPU 进⾏绘制。
离屏缓冲:
- 离屏缓冲是什么:单独的⼀个绘制 View(或 View 的⼀部分)的区域
setLayerType()和saveLayer()setLayerType()是对整个 View,不能针对onDraw()⾥⾯的某⼀具体过程- 这个⽅法常⽤来关闭硬件加速,但它的定位和定义都不只是⼀个「硬件加速开关」。
它的作⽤是为绘制设置⼀个离屏缓冲,让后⾯的绘制都单独写在这个离屏缓冲内。如果参数填写LAYER_TYPE_SOFTWARE,会把离屏缓冲设置为⼀个 Bitmap ,即使⽤软件绘制来进⾏缓冲,这样就导致在设置离屏缓冲的同时,将硬件加速关闭了。但需要知道,这个⽅法被⽤来关闭硬件加速,只是因为 Android 并没有提供⼀个便捷的⽅法在 View 级别简单地开关硬件加速⽽已。
- 这个⽅法常⽤来关闭硬件加速,但它的定位和定义都不只是⼀个「硬件加速开关」。
saveLayer()是针对 Canvas 的,所以在onDraw()⾥可以使⽤saveLayer()来圈出具体哪部
分绘制要⽤离屏缓冲- 然⽽……最新的⽂档表示这个⽅法太重了,能不⽤就别⽤,尽量⽤
setLayerType()代替
- 然⽽……最新的⽂档表示这个⽅法太重了,能不⽤就别⽤,尽量⽤