Android两种缩放旋转动画实现差异:补间动画卡顿跳变而属性动画流畅原因问询
两种Android动画实现的核心差异及问题分析
核心底层差异
两种实现分别对应Android两个不同的动画体系,底层逻辑完全不同:
- 第一种使用的是Android 早期的补间动画(View Animation):仅作用于View的绘制渲染层面,不会修改View的真实属性值,所有变换都是临时的绘制效果,动画结束后默认会恢复到View的原始状态。
- 第二种使用的是Android 3.0推出的属性动画(Property Animation):直接修改View的真实属性值,动画过程中、结束后View的属性都会和动画进度完全匹配,不存在临时变换的问题。
第一种方案卡顿、结束跳变的具体原因
1. 结束跳变的直接诱因
你在布局XML中已经给ImageView设置了android:scaleX="0.4"、android:scaleY="0.4"的默认属性,而补间动画的缩放、旋转变换是和View本身的属性叠加计算,而非覆盖:
- 动画运行时,实际显示的缩放值 = View自身scale属性值 * 补间动画的缩放系数,你的ScaleAnimation设置的是从0.1f到0.4f,对应实际显示的缩放范围是
0.4*0.1=0.04到0.4*0.4=0.16。 - 补间动画默认
fillAfter为false,动画结束后临时绘制效果直接失效,View立刻恢复到自身属性的scale=0.4状态,就会出现突然跳转到最终位置的现象。
另外你创建AnimationSet时构造参数传了true,代表所有子动画共用AnimationSet的插值器,你单独给旋转、缩放动画设置的LinearInterpolator会直接失效,默认使用AnimationSet的AccelerateDecelerateInterpolator,动画速率先快后慢,也会给人卡顿、不线性的观感。
2. 运行卡顿的性能原因
补间动画的变换需要频繁触发View及其父容器的measure、layout、draw全绘制流程,无法充分利用硬件加速的渲染优化,性能开销远高于属性动画,自然会出现卡顿感。
第二种方案流畅的原因
属性动画直接修改View的scaleX、scaleY、rotation原生属性,这些属性的更新可以直接走硬件加速渲染管线,不需要触发View的重测量、重布局流程,仅需要更新渲染层的变换矩阵即可,性能开销极低,所以运行非常流畅。且因为修改的是View的真实属性,动画结束后属性值就是你设置的目标值0.4,不存在跳变问题。
第一种方案的修复方法
如果要使用补间动画实现和第二种一致的效果,需要做三处修改:
- 给AnimationSet设置
animSet.fillAfter = true,让动画结束后保留绘制效果; - 创建AnimationSet时构造参数传
false,避免子动画的插值器被覆盖,或者直接给AnimationSet设置线性插值器; - 调整ScaleAnimation的起止值,或者直接删除布局中默认的
scaleX、scaleY属性,避免叠加计算导致的缩放值不符合预期。
内容的提问来源于stack exchange,提问作者Dmitri
相关产品推荐
相关产品推荐

