一、BottomSheet 是什么?
**BottomSheet(底部弹出层)** 是一种从屏幕底部滑出的容器视图,用来展示:
- 一组操作(类似 ActionSheet)
- 一些详细内容(例如评论区、分享面板、聊天窗口等)
它是 Material Design 设计规范中的一种常见组件,有两大类:
- Modal Bottom Sheet(模态底部弹窗)
- Persistent Bottom Sheet(持久底部面板)
二、主要几种实现方式
1️⃣** **BottomSheetDialog
最简单的方式 —— 一个从底部弹出的 Dialog。
**继承关系:
**BottomSheetDialog extends AppCompatDialog
特点:
- 本质上是一个带有
CoordinatorLayout + FrameLayout的 Dialog; - 可以用
setContentView()设置布局; - 内部自动包裹了
BottomSheetBehavior; - 适合一次性弹出内容(如菜单、弹窗);
- 支持拖动下滑关闭。
示例:
val dialog = BottomSheetDialog(context)
val view = layoutInflater.inflate(R.layout.layout_bottom_sheet, null)
dialog.setContentView(view)
dialog.show()2️⃣** **BottomSheetDialogFragment
基于Fragment的BottomSheetDialog封装版本
**继承关系:
**BottomSheetDialogFragment extends AppCompatDialogFragment
特点:
- 适合在 Fragment 架构 中使用;
- 避免内存泄漏、支持生命周期管理;
- 在 Compose、FragmentContainerView 等现代结构中更推荐;
- 通过
show()** 出,无需自己 new Dialog。**
示例:
class MyBottomSheetFragment : BottomSheetDialogFragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.layout_bottom_sheet, container, false)
}
}
// 使用
MyBottomSheetFragment().show(parentFragmentManager, "tag")3️⃣** **BottomSheetBehavior
这是最底层的核心:一个 Behavior,用于让普通 View 拥有 BottomSheet 的滑动行为。
**继承关系:
**BottomSheetBehavior
特点:
- 附加在任意 View 上(通常是
CoordinatorLayout的子 View); - 可控制滑动、展开、折叠、隐藏等状态;
- 不需要 Dialog,可以嵌入 Activity 或 Fragment 布局中;
- 常用于「半屏面板」或「可拖拽面板」场景。
XML 示例:
<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">
<!-- 主内容 -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- BottomSheet 内容 -->
<LinearLayout
android:id="@+id/bottomSheet"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="@color/white"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" />
</CoordinatorLayout>Kotlin 控制:
val bottomSheet = findViewById<LinearLayout>(R.id.bottomSheet)
val behavior = BottomSheetBehavior.from(bottomSheet)
// 展开
behavior.state = BottomSheetBehavior.STATE_EXPANDED
// 折叠
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
// 隐藏
behavior.state = BottomSheetBehavior.STATE_HIDDEN三、三者之间的关系总结
| 名称 | 类型 | 是否是 Dialog | 是否可嵌入布局 | 内部是否使用 Behavior | 典型用途 |
|---|---|---|---|---|---|
| BottomSheetDialog | Dialog | ✅ 是 | ❌ 否 | ✅ 使用了 BottomSheetBehavior | 临时弹窗 |
| BottomSheetDialogFragment | Fragment/Dialog | ✅ 是 | ❌ 否 | ✅ 使用了 BottomSheetBehavior | 弹出型 Fragment |
| BottomSheetBehavior | Behavior | ❌ 否 | ✅ 是 | ✅ 自己定义 | 页面内嵌可滑面板 |
四、常见的 BottomSheetBehavior 状态
| 状态常量 | 含义 |
|---|---|
STATE_EXPANDED | 完全展开 |
STATE_COLLAPSED | 折叠状态(只显示 peek 高度) |
STATE_HIDDEN | 完全隐藏 |
STATE_DRAGGING | 用户正在拖拽 |
STATE_SETTLING | 动画过渡中 |
五、选型建议
| 场景 | 推荐组件 |
|---|---|
| 弹出式操作菜单(如分享、选择) | BottomSheetDialog/ BottomSheetDialogFragment |
| 页面内有一个可拖拽面板(如地图底部详情卡片) | BottomSheetBehavior |
| 与 Fragment 生命周期紧密绑定 | BottomSheetDialogFragment |
| 想要像系统控件一样常驻(不打断 Activity) | BottomSheetBehavior |
更新: 2025-10-17 09:52:21
原文: https://www.yuque.com/dongpozhouzi-mshe3/zhm85g/tcg4ew0ul0vbqt8k