Moving from Dialogs to BottomSheetDialogs on Android

With Android Support Library 23.2, Google announced support for Bottom Sheets. According to Material Design, Bottom Sheets are elements displayed only as a result of a user-initiated action, used to reveal more content. They can be modal and slide from the bottom or persistent, when they’re integrated with the app to display supporting content (like Google Maps).

Making a BottomSheet on Android is quite easy, you just have to use a CoordinatorLayout as main element of your layout and attach a BottomSheet behavior to a view.

app:layout_behavior="android.support.design.widget.BottomSheetBehavior"

Then, you can receive callbacks programmatically:

// The View with the BottomSheetBehavior  
View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setBottomSheetCallback(new BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
// React to state change
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
// React to dragging events
}
});

Since they look better than simple Dialogs (well, in some situations), I’ve decided to investigate on them and eventually convert some dialogs in Glucosio to BottomSheets.

This one is the Dialog we display after a long click on a item of the RecyclerView. As you can see, it allows you to delete or edit a reading of the list.

Design Library also provides a BottomSheetDialog, a dialog styled as a bottom sheet. So you don’t have to manually make a view, attach a BottomSheet behavior and handle additional typical features of a dialog, like dim background.

First, we design a simple BottomSheet based on the old Dialog.

It’s basically made of 1 main LinearLayout (with vertical orientation) and 2 LinearLayout (with horizontal orientation) with the ImageView and the TextView.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
android:id="@+id/fragment_history_menu_bottom"
android:layout_width="match_parent"
android:layout_height="180dp"
android:orientation="vertical"
android:background="#ffffff"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:id="@+id/fragment_history_bottom_sheet_edit"
android:layout_width="match_parent"
android:layout_height="60dp"
android:clickable="true"
android:focusable="true"
android:orientation="horizontal"
android:foreground="?android:attr/selectableItemBackground"
android:padding="16dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:srcCompat="@drawable/ic_mode_edit_grey_24dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="16dp"
android:text="@string/dialog_edit"/>
</LinearLayout>
<LinearLayout
android:id="@+id/fragment_history_bottom_sheet_delete"
android:layout_width="match_parent"
android:layout_height="60dp"
android:clickable="true"
android:focusable="true"
android:orientation="horizontal"
android:foreground="?android:attr/selectableItemBackground"
android:padding="16dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:srcCompat="@drawable/ic_delete_grey_24dp"
/>
<TextView

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="16dp"
android:text="@string/dialog_delete"/>
</LinearLayout>
</LinearLayout>

Coding a BottomSheetDialog is very easy too.

BottomSheetDialog mBottomSheetDialog = new BottomSheetDialog(getActivity());
View sheetView = getActivity().getLayoutInflater().inflate(R.layout.fragment_history_bottom_sheet, null);
mBottomSheetDialog.setContentView(sheetView);
mBottomSheetDialog.show();

This code will create a new BottomSheetDialog and inflate the layout we previously made (R.layout.fragment_history_bottom_sheet).

Then, to add OnClickListeners to the buttons of the BottomSheet, we simply take the items from the sheetView we defined.

LinearLayout edit = (LinearLayout) sheetView.findViewById(R.id.fragment_history_bottom_sheet_edit);
LinearLayout delete = (LinearLayout) sheetView.findViewById(R.id.fragment_history_bottom_sheet_delete);

And then we add the listeners:

edit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Edit code here;
}
});

delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Delete code here;
}
});

We can even add some listeners to the BottomSheet and for example do something when the dialog is dismissed:

mBottomSheetDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
// Do something
}
});

Happy coding :)