如何实现BottomSheet peek高度在布局变更时的平滑动画
BottomSheet内部布局高度变更平滑动画实现方案
失效原因
你之前的方案没有生效,是因为TransitionManager.beginDelayedTransition()作用在顶层CoordinatorLayout时,BottomSheetBehavior不会自动响应内部控件可见性变化带来的高度变更,默认只会使用初始化时测量的高度值,所以会出现直接跳变的情况。
实现步骤
- 第一步:初始化
BottomSheetBehavior实例
在BottomSheetDialogFragment的onViewCreated生命周期中获取Behavior对象,开启自适应内容高度属性:
// 绑定布局中承载Behavior的FrameLayout val bottomSheetContainer = view?.findViewById<FrameLayout>(R.id.bottomSheetBehavior) ?: return val behavior = BottomSheetBehavior.from(bottomSheetContainer) // 开启内容自适应,避免固定高度限制 behavior.isFitToContents = true
- 第二步:调整可见性切换逻辑
将动画作用范围限制在BottomSheet内部的内容容器,修改可见性后主动触发Behavior高度更新:
// 切换可见性前启动过渡动画,作用在内容布局即可,不需要传入顶层CoordinatorLayout TransitionManager.beginDelayedTransition( bottomSheetContent, // 你布局中的ConstraintLayout内容容器 AutoTransition().apply { duration = 300 // 可自定义动画时长 } ) // 这里修改你要展开/收起的卡片可见性 yourTargetCard.isVisible = !yourTargetCard.isVisible // 主动通知Behavior更新适配新的内容高度 bottomSheetContent.post { behavior.peekHeight = bottomSheetContent.measuredHeight }
- 第三步:可选冲突处理
如果出现动画过程中底部空白、布局闪烁的问题,可禁用Behavior的默认状态切换动画避免冲突:
behavior.isHideable = false // 不需要收起至隐藏的话可开启,减少动画冲突 // 若不需要拖拽调整高度,也可禁用拖拽功能 behavior.isDraggable = false
注意事项
过渡动画的作用范围不要覆盖顶层CoordinatorLayout,仅作用于BottomSheet内部的内容容器即可,避免和BottomSheet自带的滑动逻辑冲突出现异常效果。
内容的提问来源于stack exchange,提问作者BlazeCodeDev
相关产品推荐
相关产品推荐

