属性动画和硬件加速
属性动画
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
AccelerateInterpolator
DecelerateInterpolator
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()
代替
- 然⽽……最新的⽂档表示这个⽅法太重了,能不⽤就别⽤,尽量⽤