Android MotionLayout配合RecyclerView滚动时AppBar动画异常问题求助
问题根因与解决方案
核心冲突原因
你在MotionScene的Transition节点中添加了空的<OnSwipe/>标签,该标签会让MotionLayout自行拦截处理触摸滚动事件,和AppBarLayout的滚动监听、RecyclerView的嵌套滚动逻辑产生控制权冲突,是导致RecyclerView滚动时动画异常的主要原因。滚动非RecyclerView区域时事件传递链路更短,冲突概率低,所以表现正常。
具体修复步骤
移除冗余的OnSwipe配置
删除fragment_profile_xml_profile_header_info_scene.xml中Transition节点下的空<OnSwipe/>标签,当前方案是通过AppBarLayout的偏移手动驱动MotionLayout进度,完全不需要该配置参与滑动处理。优化偏移监听的边界处理
原监听逻辑未做边界校验,可能出现空指针、除零、进度越界的问题,修改为如下代码:
private fun coordinateMotion() { val appBarLayout: AppBarLayout = binding.appbarLayout ?: return val motionLayout: MotionLayout = binding.profileHeaderInfo as MotionLayout val listener = AppBarLayout.OnOffsetChangedListener { _, verticalOffset -> val scrollRange = appBarLayout.totalScrollRange if (scrollRange == 0) return@OnOffsetChangedListener val seekPosition = -verticalOffset / scrollRange.toFloat() // 限制进度在合法区间避免动画异常 motionLayout.progress = seekPosition.coerceIn(0f, 1f) } appBarLayout.addOnOffsetChangedListener(listener) }
- 修正滚动标志位冲突
当前给MotionLayout设置的滚动标志位scroll|enterAlways|snap|exitUntilCollapsed存在逻辑冲突,enterAlways和exitUntilCollapsed的滚动优先级互斥,根据折叠后常驻顶部的需求,修改为:
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
- 可选优化:禁用自动过渡
如果修改后仍存在动画跳变,给MotionLayout添加如下属性,避免其自动触发过渡动画和手动设置进度的逻辑冲突:
app:motionProgress="0" app:layout_constraintMotion_autoTransition="none"
内容的提问来源于stack exchange,提问作者Milad Targholi
相关产品推荐
相关产品推荐

