Kotlin Bottom Sheet上滑联动头像动画实现问题咨询
核心问题说明
你当前的实现同时使用了BottomSheetBehavior和MotionLayout自带的OnSwipe滑动逻辑,二者存在触摸事件冲突,且MotionScene中未配置头像的动效规则、也没有建立BottomSheet滑动进度和MotionLayout进度的绑定关系,所以无法实现联动。
修复步骤
1. 修正MotionScene配置
删除原有motion.xml中的<OnSwipe>标签、以及重复冗余的KeyAttribute配置,补充头像的动效约束,示例如下:
<?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:motion="http://schemas.android.com/apk/res-auto"> <Transition motion:constraintSetStart="@+id/start" motion:constraintSetEnd="@+id/end" motion:duration="1000"> <KeyFrameSet> <!-- 保留你需要的BottomSheet动效 --> <KeyAttribute motion:motionTarget="@+id/bottomSheetLayout" motion:framePosition="100" android:alpha="0" /> <KeyAttribute motion:motionTarget="@+id/bottomSheetLayout" motion:framePosition="100" android:scaleX="0" /> <KeyAttribute motion:motionTarget="@+id/bottomSheetLayout" motion:framePosition="100" android:scaleY="0" /> <!-- 按需添加头像的关键帧动效,比如滑动到一半时半透明 --> <KeyAttribute motion:motionTarget="@+id/background_imageView" motion:framePosition="50" android:alpha="0.7" /> </KeyFrameSet> </Transition> <ConstraintSet android:id="@+id/start"> <!-- 头像初始状态约束,和布局原有配置保持一致 --> <Constraint android:id="@+id/background_imageView" android:layout_width="155dp" android:layout_height="155dp" android:layout_marginStart="15dp" android:layout_marginTop="15dp" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent" /> <Constraint android:id="@+id/bottomSheetLayout" android:layout_width="match_parent" android:layout_height="match_parent" /> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <!-- 头像结束状态约束,示例为缩小移动到右上角 --> <Constraint android:id="@+id/background_imageView" android:layout_width="45dp" android:layout_height="45dp" android:layout_marginEnd="15dp" android:layout_marginTop="15dp" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent" /> <Constraint android:id="@+id/bottomSheetLayout" android:layout_width="match_parent" android:layout_height="1dp" /> </ConstraintSet> </MotionScene>
2. 绑定BottomSheet滑动与MotionLayout进度
在Activity/Fragment中拿到BottomSheet的Behavior实例,通过滑动回调同步MotionLayout的进度:
// 注意此处绑定的是你布局中配置了CustomBottomSheetBehavior的bottomSheetLayout val bottomSheetBehavior = BottomSheetBehavior.from(binding.bottomSheetLayout) bottomSheetBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { override fun onStateChanged(bottomSheet: View, newState: Int) { // 按需处理状态折叠/展开的边界逻辑即可 } override fun onSlide(bottomSheet: View, slideOffset: Float) { // 将BottomSheet的滑动偏移量转为[0,1]区间的进度,同步给MotionLayout val motionProgress = slideOffset.coerceIn(0f, 1f) binding.motionLayout.progress = motionProgress } })
3. 可选优化
- 直接删除布局中包裹头像的冗余
ConstraintLayout(id为layout的那层),将头像CardView直接放在MotionLayout下,减少布局层级 - 检查自定义的
CustomBottomSheetBehavior逻辑,避免不必要的触摸事件拦截导致滑动卡顿
内容的提问来源于stack exchange,提问作者rengineer
相关产品推荐
相关产品推荐

