A rounded modal bottom sheet is a combination of a background drawable and a dialog theme. This older Android example rounded only the upper corners and left the sheet connected to the bottom edge.
Historical Material example. Theme names, resources, and SDK behavior belong to the original project. The snippets have not been rebuilt against a current Android toolchain.
Shape the background
bg_bottom_sheet_dialog_fragment.xml defines the corner radii, top padding, and fill:
<!-- Drawable used for the bottom sheet dialog background -->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:topLeftRadius="@dimen/bottom_sheet_corner_radius"
android:topRightRadius="@dimen/bottom_sheet_corner_radius" />
<padding android:top="@dimen/bottom_sheet_top_padding" />
<solid android:color="@color/primary" />
</shape>
Connect the dimensions and fragment
The original note placed the dimens.xml values and RoundedBottomSheetDialogFragment.kt in one listing. They belong in separate resource and Kotlin files; the filename line separates the two portions below.
<dimen name="bottom_sheet_corner_radius">16dp</dimen>
<dimen name="bottom_sheet_top_padding">8dp</dimen>
RoundedBottomSheetDialogFragment.kt
package com.your.package
import android.app.Dialog
import android.os.Bundle
import com.your.package.R
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
/**
* BottomSheetDialog fragment that uses a custom
* theme which sets a rounded background to the dialog
* and doesn't dim the navigation bar
*/
open class RoundedBottomSheetDialogFragment : BottomSheetDialogFragment() {
override fun getTheme(): Int = R.style.BottomSheetDialogTheme
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = BottomSheetDialog(requireContext(), theme)
}
The fragment chooses the custom theme and constructs a BottomSheetDialog. Resource names such as primary and white refer to the surrounding application.
Apply the dialog styles
The API-21-specific style adjusts status and navigation bar colors:
<!-- v21 styles, you can merge these two if your minSdkVersion is >= 21 -->
<resources>
<style name="BottomSheetDialogTheme" parent="BaseBottomSheetDialog">
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@color/white</item>
</style>
</resources>
The base styles connect the background drawable to the bottom sheet:
<resources>
<!-- set the rounded drawable as background to your bottom sheet -->
<style name="BottomSheet" parent="@style/Widget.Design.BottomSheet.Modal">
<item name="android:background">@drawable/bg_bottom_sheet_dialog_fragment</item>
</style>
<style name="BaseBottomSheetDialog" parent="@style/Theme.Design.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="bottomSheetStyle">@style/BottomSheet</item>
</style>
<style name="BottomSheetDialogTheme" parent="BaseBottomSheetDialog" />
</resources>
The useful boundary is between the sheet’s shape and the window’s system-bar treatment. They are related visual choices, but changing one does not automatically validate the other across Android versions.