type
status
date
slug
summary
tags
category
password
icon
属性动画
ViewPropertyAnimator
使⽤
View.animate()
创建对象,以及使⽤ ViewPropertyAnimator.translationX()
等⽅法来设置动画;可以连续调⽤来设置多个动画;
可以⽤
setDuration()
来设置持续时间;可以⽤
setStartDelay()
来设置开始延时;以及其他⼀些便捷⽅法。
ObjectAnimator
使⽤
ObjectAnimator.ofXxx()
来创建对象,以及使⽤ ObjectAnimator.start()
来主动启动动画。它的优势在于,可以为⾃定义属性设置动画。另外,⾃定义属性需要设置 getter 和 setter ⽅法,并且 setter ⽅法⾥需要调⽤
invalidate()
来触发重绘:可以使⽤ setDuration() 来设置持续时间;
可以⽤ setStartDelay() 来设置开始延时;
以及其他⼀些便捷⽅法。
Interpolator
插值器,⽤于设置时间完成度到动画完成度的计算公式,直⽩地说即设置动画的速度曲线,通过
setInterpolator(Interpolator)
⽅法来设置。常⽤的有:
AccelerateDecelerateInterpolator
:先加速再减速
AccelerateInterpolator
:一直加速,终点戛然而止
DecelerateInterpolator
:减速停止
LinearInterpolator
:匀速
PropertyValuesHolder
⽤于设置更加详细的动画,例如多个属性应⽤于同⼀个对象:
或者,配合使⽤
Keyframe
,对⼀个属性分多个段:AnimatorSet
将多个 Animator 合并在⼀起使⽤,先后顺序或并列顺序都可以:
TypeEvaluator
⽤于设置动画完成度到属性具体值的计算公式。默认的
ofInt()
ofFloat()
已经有了⾃带的 IntEvaluator FloatEvaluator
,但有的时候需要⾃⼰设置 Evaluator
。例如,对于颜⾊,需要为 int 类型的颜⾊设置 ArgbEvaluator
,⽽不是让它们使⽤ IntEvaluator
:如果你对
ArgbEvaluator
的效果不满意,也可以⾃⼰写⼀个 HsvEvaluator
另外,对于不⽀持的类型,也可以使⽤
ofObject()
来在创建 Animator
的同时就设置上Evaluator
,⽐如 NameEvaluator
:Listeners
和 View 的点击、⻓按监听器⼀样,
Animator
也可以使⽤ setXxxListener()
、addXxxListener()
来设置监听器。ValueAnimator
这是最基本的
Animator
,它不和具体的某个对象联动,⽽是直接对两个数值进⾏渐变计算。使⽤很少。硬件加速
硬件加速是什么?
- 使⽤ CPU 绘制到 Bitmap,然后把 Bitmap 贴到屏幕,就是软件绘制;
- 使⽤ CPU 把绘制内容转换成
GPU 操作
,交给 GPU,由 GPU 负责真正的绘制,就叫硬件绘制;
- 使⽤ GPU 绘制就叫做硬件加速
怎么就加速了?
- GPU 分摊了⼯作
- GPU 绘制简单图形(例如⽅形、圆形、直线)在硬件设计上具有先天优势,会更快
- 流程得到优化(重绘流程涉及的内容更少)
硬件加速的缺陷: 兼容性。由于使⽤ GPU 的绘制(暂时)⽆法完成某些绘制,因此对于⼀些特定的 API,需要关闭硬件加速来转回到使⽤ CPU 进⾏绘制。 Android 官方提供的那些 API 不支持硬件加速
离屏缓冲:
- 离屏缓冲是什么:单独的⼀个绘制 View(或 View 的⼀部分)的区域
setLayerType()
和saveLayer()
setLayerType()
是对整个 View,不能针对onDraw()
⾥⾯的某⼀具体过程- 这个⽅法常⽤来关闭硬件加速,但它的定位和定义都不只是⼀个「硬件加速开关」。它的作⽤是为绘制设置⼀个离屏缓冲,让后⾯的绘制都单独写在这个离屏缓冲内。如果参数填写
LAYER_TYPE_SOFTWARE
,会把离屏缓冲设置为⼀个 Bitmap ,即使⽤软件绘制来进⾏缓冲,这样就导致在设置离屏缓冲的同时,将硬件加速关闭了。但需要知道,这个⽅法被⽤来关闭硬件加速,只是因为 Android 并没有提供⼀个便捷的⽅法在View 级别简单地开关硬件加速⽽已。 saveLayer()
是针对 Canvas 的,所以在onDraw()
⾥可以使⽤saveLayer()
来圈出具体哪部分绘制要⽤离屏缓冲,- 然⽽
saveLayer()
会每次都创建一个离屏缓冲,用完了就丢弃这个离屏缓冲,这样就比较耗费性能,所以官方最新的⽂档表示这个⽅法太重了,能不⽤就别⽤(但是该用还是得用),尽量⽤setLayerType()
代替
这玩意的用处目前就两个:
- 使用
setLayerType(LAYER_TYPE_SOFTWARE, null)
关闭View级别硬件加速
- 使用
setLayerType(LAYER_TYPE_HARDWARE, null)
开启离屏缓冲后,系统的属性动画就能过通过,通过withLayer()
使得动画使用GPU的方式执行
- 作者:shuouyang
- 链接:https://notion-tree.vercel.app/article/47b244cb-404c-4719-a5ff-c42e80b0fb8a
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。