一、BottomSheet 是什么?

**BottomSheet(底部弹出层)** 是一种从屏幕底部滑出的容器视图,用来展示:

  • 一组操作(类似 ActionSheet)
  • 一些详细内容(例如评论区、分享面板、聊天窗口等)

它是 Material Design 设计规范中的一种常见组件,有两大类:

  1. Modal Bottom Sheet(模态底部弹窗)
  2. 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

基于FragmentBottomSheetDialog封装版本

**继承关系:
**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 extends CoordinatorLayout.Behavior

特点:

  • 附加在任意 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典型用途
BottomSheetDialogDialog✅ 是❌ 否✅ 使用了 BottomSheetBehavior临时弹窗
BottomSheetDialogFragmentFragment/Dialog✅ 是❌ 否✅ 使用了 BottomSheetBehavior弹出型 Fragment
BottomSheetBehaviorBehavior❌ 否✅ 是✅ 自己定义页面内嵌可滑面板

四、常见的 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


相关笔记