Material 3 Bottom Sheets
Overview
Bottom Sheets are surfaces anchored to the screen bottom, displaying supplementary content.
Material 3 Bottom Sheets support two variants: Standard (persistent, co-exists with main UI) and Modal (blocks main UI, dialog-like). Using BottomSheetBehavior
for Standard and BottomSheetDialogFragment
for Modal, they offer states like STATE_COLLAPSED
, STATE_EXPANDED
, and STATE_HIDDEN
, with customizable behaviors like peek height and draggability. This guide covers implementation, accessibility, and theming.

Getting Started
- Add Material Components for Android library dependency
- Use
BottomSheetBehavior
for Standard orBottomSheetDialogFragment
for Modal - Apply
Theme.Material3.*
for styling - Include
BottomSheetDragHandleView
for accessibility
Accessibility
- Set
android:contentDescription
on content for TalkBack - Use
BottomSheetDragHandleView
(48dp min size) for drag support - Ensure Modal sheets dismiss clearly for screen readers
Behavior and States
- States:
STATE_COLLAPSED
,STATE_EXPANDED
,STATE_HALF_EXPANDED
,STATE_HIDDEN
,STATE_DRAGGING
,STATE_SETTLING
- Configure
peekHeight
,hideable
,fitToContents
,skipCollapsed
,draggable
- Handle state changes with
BottomSheetCallback
val bottomSheet = findViewById<FrameLayout>(R.id.standard_bottom_sheet)
val behavior = BottomSheetBehavior.from(bottomSheet)
behavior.state = BottomSheetBehavior.STATE_EXPANDED
behavior.peekHeight = 100
behavior.isHideable = true
behavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
// Handle state change
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {
// Handle slide
}
})
Bottom Sheet Variants
- Standard: Persistent, co-exists with main UI
- Modal: Blocks main UI, dialog-like with scrim
Standard Bottom Sheet

- Persistent, allows simultaneous UI interaction
- Ideal for secondary content like maps or controls
Example
<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">
<!-- Main content -->
<FrameLayout
android:id="@+id/standard_bottom_sheet"
style="@style/Widget.Material3.BottomSheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
app:behavior_peekHeight="100dp"
app:behavior_hideable="false">
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
android:id="@+id/drag_handle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="@string/drag_handle_desc"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title"
android:textAppearance="?attr/textAppearanceTitleMedium"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/supporting_text"
android:textAppearance="?attr/textAppearanceBodyMedium"/>
</LinearLayout>
</FrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
val standardBottomSheet = findViewById<FrameLayout>(R.id.standard_bottom_sheet)
val behavior = BottomSheetBehavior.from(standardBottomSheet)
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
Standard Bottom Sheet Anatomy

Component | Description | Collapsed State | Expanded State | Hidden State |
---|---|---|---|---|
Container | Content container, 1dp elevation | Visible at peekHeight (e.g., 100dp) | Visible at max height (640dp) | Hidden |
Drag Handle | Optional, 48dp min size for accessibility | Visible if set | Visible if set | Hidden |
Modal Bottom Sheet

- Blocks main UI with a scrim
- Ideal for focused choices or dialogs
Example
<!-- res/layout/modal_bottom_sheet_content.xml -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="@string/drag_handle_desc"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title"
android:textAppearance="?attr/textAppearanceTitleMedium"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/supporting_text"
android:textAppearance="?attr/textAppearanceBodyMedium"/>
<com.google.android.material.button.MaterialButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/action"
style="?attr/materialButtonStyle"/>
</LinearLayout>
class ModalBottomSheet : BottomSheetDialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.modal_bottom_sheet_content, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val behavior = (dialog as BottomSheetDialog).behavior
behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
companion object {
const val TAG = "ModalBottomSheet"
}
}
// In Activity
val modalBottomSheet = ModalBottomSheet()
modalBottomSheet.show(supportFragmentManager, ModalBottomSheet.TAG)
Modal Bottom Sheet Anatomy

Component | Description | Collapsed State | Expanded State | Hidden State |
---|---|---|---|---|
Container | Modal container, 1dp elevation | Visible at peekHeight (e.g., auto) | Visible at max height (640dp) | Hidden |
Drag Handle | Optional, 48dp min size for accessibility | Visible if set | Visible if set | Hidden |
Scrim | Dims main UI | Visible, semi-transparent | Visible, semi-transparent | Hidden |
Attributes and Usage
Element | Attribute | Related Method(s) | Default Value | Usage Description |
---|---|---|---|---|
Sheet | app:backgroundTint |
N/A | ?attr/colorSurfaceContainerLow |
Sets background color |
Sheet | app:shapeAppearance |
N/A | ?attr/shapeAppearanceCornerExtraLarge |
Sets corner shape |
Sheet | android:elevation |
N/A | 1dp | Sets elevation |
Sheet | android:maxWidth |
setMaxWidth , getMaxWidth |
640dp | Sets max width |
Behavior | app:behavior_peekHeight |
setPeekHeight , getPeekHeight |
auto | Sets collapsed height |
Behavior | app:behavior_hideable |
setHideable , isHideable |
false (Standard), true (Modal) | Allows hiding sheet |
Behavior | app:behavior_fitToContents |
setFitToContents , isFitToContents |
true | Fits sheet to content height |
Behavior | app:behavior_skipCollapsed |
setSkipCollapsed , getSkipCollapsed |
false | Skips collapsed state |
Behavior | app:behavior_draggable |
setDraggable , isDraggable |
true | Enables dragging |
Theming Bottom Sheets

- Customize color and shape
- Use
res/values/styles.xml
for theming
Example
<style name="Theme.App" parent="Theme.Material3.*">
<item name="bottomSheetDialogTheme">@style/ThemeOverlay.App.BottomSheetDialog</item>
</style>
<style name="ThemeOverlay.App.BottomSheetDialog" parent="ThemeOverlay.Material3.BottomSheetDialog">
<item name="bottomSheetStyle">@style/Widget.App.BottomSheet</item>
</style>
<style name="Widget.App.BottomSheet" parent="Widget.Material3.BottomSheet.Modal">
<item name="backgroundTint">@color/shrine_pink_light</item>
<item name="shapeAppearance">@style/ShapeAppearance.App.LargeComponent</item>
</style>
<style name="ShapeAppearance.App.LargeComponent" parent="ShapeAppearance.Material3.LargeComponent">
<item name="cornerFamily">cut</item>
<item name="cornerSize">24dp</item>
</style>
Material Design Documentation
- Adheres to Material Design guidelines for Bottom Sheets
- Covers design, behavior, theming specifications
- Includes accessibility and state management
- Refer to Material Design documentation for full details
FAQ
What are Material 3 Bottom Sheets?
- Surfaces anchored to the screen bottom for supplementary content
How many variants are there?
- Two variants: Standard and Modal
When to use a Modal Bottom Sheet?
- Use for focused choices that block main UI interaction
How to make them accessible?
- Set content descriptions; use
BottomSheetDragHandleView
Can I customize appearance?
- Yes, theme via
res/values/styles.xml
How to add the Material 3 library?
- Include Material Components for Android library
Are there updates for the latest standards?
- Reflects latest Material 3 standards for Bottom Sheets
Tags:
MDC Android