Android BottomSheetDialog

A couple months ago, I implemented my first Support Library BottomSheetDialog at work. I then decided to explore it a bit further in an example app:

Example “warning” dialog

There are three choices when implementing a Support Library (23.2) Material Design bottom sheet — a container view with a BottomSheetBehavior, a BottomSheetDialogFragment, or a BottomSheetDialog. There are plenty examples of the first two on the interwebs, hence I decided to write a quick post about BottomSheetDialog.

Why BottomSheetDialog?

But first, you might be wondering why use a BottomSheetDialog over a container view with BottomSheetBehavior?

Depends on how you want to use it — the latter covers the persistent bottom sheet case, whereas BottomSheetDialog (and fragment) covers the modal bottom sheet use case.

The BottomSheetDialog essentially wraps the content view of the dialog in a FrameLayout inside of a CoordinatorLayout. The BottomSheetDialog handles setting the BottomSheetBehavior on this FrameLayout, which is convenient!

Show me the code

Below is a BottomSheetDialog with dialog_coffee.xml as it’s content view.

public CoffeeDialog(Context context) {

View contentView = View.inflate(getContext(), R.layout.dialog_coffee, null);



Note that I had to make a custom theme (shown below), inheriting from the BottomSheetDialog theme to have the alpha of the background color show the intended transparency, and have it not dismiss when touched outside. I only wanted the dialog to dismiss when the user either drags it down or presses the “X” on the top right.

Using setCanceledOnTouchOutside(false) in code didn’t work, however the custom theme below did the trick!

<style name="CoffeeDialog" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:windowCloseOnTouchOutside">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:colorBackground"> @android:color/transparent</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:backgroundDimAmount">0.3</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>

How do I configure the BottomSheetCallback?

BottomSheetCallbacks are tied to BottomSheetBehaviors and monitor events through onSlide(..) and onStateChanged(..) callbacks. You can retrieve the BottomSheetBehavior from the ViewParent of the content view, and set the BottomSheetCallback there.

private void configureBottomSheetBehavior(View contentView) {
BottomSheetBehavior mBottomSheetBehavior = BottomSheetBehavior.from((View) contentView.getParent());

if (mBottomSheetBehavior != null) {
mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {

public void onStateChanged(@NonNull View bottomSheet, int newState) {
//showing the different states
switch (newState) {
case BottomSheetBehavior.STATE_HIDDEN:
dismiss(); //if you want the modal to be dismissed when user drags the bottomsheet down
case BottomSheetBehavior.STATE_EXPANDED:
case BottomSheetBehavior.STATE_COLLAPSED:
case BottomSheetBehavior.STATE_DRAGGING:
case BottomSheetBehavior.STATE_SETTLING:

public void onSlide(@NonNull View bottomSheet, float slideOffset) {

Ofcourse, explicitly setting the BottomSheetCallback isn’t necessary unless you want to respond to state changes of the bottom sheet.

I found implementing the BottomSheetDialog pretty straightforward, except for setCanceledOnTouchOutside(false) not working as expected!

From a design perspective, that makes sense because the material design documentation states that it can be dismissed when the outside is touched. However, it felt weird that the option to configure that functionality exists in the code, but doesn’t work as expected, whereas it works for regular dialogs. But, the custom theme saved the day!

There are other quirks with it, but I personally haven’t encountered them yet. There are more fun things you can do with bottom sheets that are covered here. Looking forward to having fun with these myself! Enjoy!