如何让Android布局尺寸变化动画更流畅?
解决Android布局尺寸变化动画卡顿问题
你的代码卡顿主要是因为频繁触发视图树的测量/布局流程,以及两个动画的更新不同步导致的。下面是具体的优化方案:
一、优化现有ValueAnimator实现
把宽高的动画合并为一个,减少requestLayout的调用次数,避免重复触发布局计算:
// 用PropertyValuesHolder同时处理宽高百分比的动画 val animator = ValueAnimator.ofPropertyValuesHolder( PropertyValuesHolder.ofFloat("heightPercent", beforeHeight, afterHeight), PropertyValuesHolder.ofFloat("widthPercent", beforeWidth, afterWidth) ).apply { duration = 200 // 适当延长时长,视觉更流畅 addUpdateListener { anim -> val layoutParams = binding.mainFragmentCalendarLayout.layoutParams as ConstraintLayout.LayoutParams // 一次性更新宽高参数 layoutParams.matchConstraintPercentHeight = anim.getAnimatedValue("heightPercent") as Float layoutParams.matchConstraintPercentWidth = anim.getAnimatedValue("widthPercent") as Float // 只调用一次requestLayout,触发布局更新 binding.mainFragmentCalendarLayout.requestLayout() // 无需调用invalidate,requestLayout会自动触发重绘 } } animator.start()
二、推荐使用TransitionManager(更简洁高效)
Android官方的Transition框架专门针对布局变化做了优化,能自动捕捉布局前后状态,生成流畅的过渡动画,无需手动处理每一帧:
// 开启延迟过渡,框架会自动处理动画 TransitionManager.beginDelayedTransition(binding.mainFragmentRoot) // 直接修改最终的布局参数 val layoutParams = binding.mainFragmentCalendarLayout.layoutParams as ConstraintLayout.LayoutParams layoutParams.matchConstraintPercentHeight = afterHeight layoutParams.matchConstraintPercentWidth = afterWidth binding.mainFragmentCalendarLayout.layoutParams = layoutParams
三、原代码卡顿的核心原因
- 两个独立的
ValueAnimator分别更新宽高,容易出现同步偏差,导致动画脱节。 - 每次动画帧都调用
requestLayout,会触发整个视图树的measure和layout流程,频繁调用会大幅增加CPU负载。 - 多余的
invalidate调用:requestLayout已经会触发视图重绘,无需额外调用。
额外优化建议
- 动画时长建议设置在200-300ms之间,过短的时长(150ms)会让动画显得生硬,也更容易出现卡顿。
- 确保布局层级不要过于复杂,减少动画过程中的测量计算量。
- 确认页面已开启硬件加速(默认开启),可在AndroidManifest或布局xml中添加
android:hardwareAccelerated="true"。
内容的提问来源于stack exchange,提问作者jihunAn
相关产品推荐
相关产品推荐

