在Fragment中实现bottomSheet行为 支持跳转后下拉隐藏且可访问背景UI
普通Fragment实现BottomSheet下拉关闭效果方案
前置说明
无需修改Fragment B的继承关系,直接通过CoordinatorLayout配合BottomSheetBehavior即可实现需求,同时保留背景UI的交互权限。
步骤1:调整Fragment B的根布局
Fragment B的布局需要以CoordinatorLayout为根节点,内容区域配置BottomSheetBehavior属性,示例代码如下:
<!-- fragment_b.xml --> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- BottomSheet内容容器 --> <LinearLayout android:id="@+id/bs_content" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" app:behavior_peekHeight="300dp" <!-- 初始展示高度,按需调整 --> app:behavior_hideable="true" <!-- 允许滑到底部隐藏 --> app:behavior_skipCollapsed="false"> <!-- 此处放置Fragment B的业务控件 --> </LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
步骤2:Fragment B中绑定滑动逻辑
在onViewCreated生命周期中初始化Behavior,监听滑动状态实现下滑销毁,示例代码如下:
// Fragment B 业务代码 private var bottomSheetBehavior: BottomSheetBehavior<View>? = null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val contentView = view.findViewById<View>(R.id.bs_content) bottomSheetBehavior = BottomSheetBehavior.from(contentView) // 初始设置为展开状态 bottomSheetBehavior?.state = BottomSheetBehavior.STATE_EXPANDED // 配置状态监听 bottomSheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { override fun onStateChanged(bottomSheet: View, newState: Int) { // 滑动到隐藏状态时销毁当前Fragment if (newState == BottomSheetBehavior.STATE_HIDDEN) { parentFragmentManager.popBackStack() // 若未加回退栈,可直接调用remove: // parentFragmentManager.beginTransaction().remove(this@FragmentB).commit() } } override fun onSlide(bottomSheet: View, slideOffset: Float) { // 可选配置:滑动时调整背景透明度增强交互感 requireView().alpha = 1 + slideOffset } }) } // 可选:拦截返回键,点击返回先触发下滑隐藏 fun onBackPressed(): Boolean { return if (bottomSheetBehavior?.state != BottomSheetBehavior.STATE_HIDDEN) { bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN true } else { false } }
步骤3:Fragment A跳转逻辑调整
原有容器挂载逻辑保持不变,仅需添加回退栈配置即可:
// Fragment A 按钮点击跳转逻辑 findViewById<Button>(R.id.jump_btn).setOnClickListener { parentFragmentManager.beginTransaction() .replace(R.id.your_fragment_container, FragmentB::class.java, null) .addToBackStack(null) // 必须添加,否则销毁后无法回到Fragment A .commit() }
常见报错排查
- 若报
The view is not a child of CoordinatorLayout:检查内容布局是否为CoordinatorLayout的直接子节点,且已正确配置layout_behavior属性 - 若滑动无响应:检查
behavior_hideable是否设置为true,peekHeight不要配置为0 - 若背景无法交互:确认挂载Fragment B用的是
replace/add方式,未设置屏蔽背景触摸的Window flag
内容的提问来源于stack exchange,提问作者Kaviarasan Sandirasekaran
相关产品推荐
相关产品推荐

