MotionLayout中KeyAttribute无视framePosition,visibility属性动画起始即生效?
问题根因
你遇到的现象和设置的framePosition数值无关,本质是MotionLayout处理离散属性时的固有逻辑导致的:
visibility是没有连续插值空间的离散属性
MotionLayout的KeyFrame体系仅对alpha、translationX这类可以按进度计算中间值的连续属性生效。对于View.VISIBLE(0)、View.INVISIBLE(4)、View.GONE(8)这类离散整型值,引擎本身没有实现帧间过渡的计算逻辑。只要你通过CustomAttribute挂载该属性,引擎会直接跳过帧位置判断,在动画启动的第一帧就把配置值应用到目标View上,完全不识别你设置的framePosition阈值。- 缺少起始帧的属性基准配置
你当前的配置只在framePosition=80的位置声明了目标View的GONE状态,没有在0帧(动画起始点)给同一批View配置初始的VISIBLE基准值。MotionLayout解析配置时找不到完整的属性时间轴映射,会把所有写好的CustomAttribute值直接当成全局生效值,从动画启动就应用到View上。
可落地的修复方案
- 不要直接依赖
CustomAttribute配置visibility属性,这类场景下它的行为完全不受KeyFrame的帧位置控制。如果要实现动画进度到80%时再隐藏对应View:- 如果接受80%帧位置的直接跳变,可以在同一个
KeyFrameSet中给三个目标View都补充framePosition=0的KeyAttribute,设置初始visibility=VISIBLE(对应整数值0),让MotionLayout识别到完整的属性时间轴区间,此时动画到80%进度时才会触发GONE的状态切换。 - 如果需要更顺滑的效果,完全绕开引擎对离散属性的处理:先通过
CustomAttribute配置alpha值的0到1过渡,给MotionLayout添加TransitionListener监听动画进度,当进度达到80%时再手动调用View的setVisibility(View.GONE)。
- 如果接受80%帧位置的直接跳变,可以在同一个
- 注意:从MotionLayout 2.0到当前的稳定版本,始终没有修复
CustomAttribute配置离散属性时无视帧位置的问题,只要用该方式设置visibility,不管把framePosition改成0、50还是100,属性都会在动画启动瞬间生效。
内容的提问来源于stack exchange,提问作者Viktor
相关产品推荐
相关产品推荐

