Currently, we are figuring how to implement such a bottom sheet, with the following requirements.
- Round corner bottom sheet.
- Fixed height bottom sheet.
- Non-draggable bottom sheet.
- Content in the bottom sheet is scrollable.
- Hide bottom sheet when we tap on non-bottom sheet item.
- Hide sheet when we press on back button.
- A non-blocking bottom sheet. When we tap on non-bottom sheet item, the tapped item will get focus and bottom sheet will hide.
We are considering, whether to use BottomSheetBehavior or BottomSheetDialogFragment.
So far, we manage to implement all the requirements, by using BottomSheetBehavior.
Implementation using BottomSheetBehavior
However, we do not really like the solution as
- It increases the complexity of our
Activity's layout, where additionalCoordinatorLayoutis required. - Manual touch event code handling is required at
Activity, to achieve requirement 5, 6 & 7 (Hide bottom sheet).
Here's the code snippet by using BottomSheetBehavior.
public class MainActivity extends AppCompatActivity {
private BottomSheetBehavior bottomSheetBehavior;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.image_button_0).setOnClickListener(view -> demo0());
findViewById(R.id.image_button_1).setOnClickListener(view -> demo1());
// 7) A non-blocking bottom sheet. When we tap on non-bottom sheet item, the tapped item
// will get focus and bottom sheet will hide.
findViewById(R.id.edit_text_0).setOnFocusChangeListener((view, b) -> {
if (b) {
hideBottomSheet();
}
});
// 7) A non-blocking bottom sheet. When we tap on non-bottom sheet item, the tapped item
// will get focus and bottom sheet will hide.
findViewById(R.id.edit_text_1).setOnFocusChangeListener((view, b) -> {
if (b) {
hideBottomSheet();
}
});
}
public void demo0() {
DemoBottomDialogFragment demoBottomDialogFragment = DemoBottomDialogFragment.newInstance();
demoBottomDialogFragment.show(getSupportFragmentManager(), "demoBottomDialogFragment");
}
public void demo1() {
// 1) Round corner bottom sheet.
View view = findViewById(R.id.bottom_sheet_layout_2);
/*
2) Fixed height bottom sheet.
3) Non-draggable bottom sheet.
4) Content in the bottom sheet is scrollable.
*/
this.bottomSheetBehavior = BottomSheetBehavior.from(view);
bottomSheetBehavior.setPeekHeight(900, true);
bottomSheetBehavior.setDraggable(false);
}
private boolean hideBottomSheet() {
if (this.bottomSheetBehavior != null) {
this.bottomSheetBehavior.setPeekHeight(0, true);
this.bottomSheetBehavior = null;
return true;
}
return false;
}
@Override
public void onBackPressed() {
// 5) Hide bottom sheet when we tap on non-bottom sheet item.
if (hideBottomSheet()) {
return;
}
super.onBackPressed();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// 6) Hide sheet when we press on back button.
hideBottomSheet();
return super.onTouchEvent(event);
}
}
If we were using BottomSheetDialogFragment, the code will be way more simpler. We can achieve all requirements, except number 7
- A non-blocking bottom sheet. When we tap on non-bottom sheet item, the tapped item will get focus and bottom sheet will hide.
Here's the outcome of BottomSheetDialogFragment.
Implementation using BottomSheetDialogFragment
The good thing of using BottomSheetDialogFragment is that,
- Will not increase the complexity of
Activity's layout. - No code required at
Activity, to hide the bottom sheet (Requirement 5, 6. Requirement 7 still not achievable)
Here's the code snippet.
public class DemoBottomDialogFragment extends BottomSheetDialogFragment {
public static DemoBottomDialogFragment newInstance() {
return new DemoBottomDialogFragment();
}
@NonNull
@Override public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
// https://stackoverflow.com/questions/58651661/how-to-set-max-height-in-bottomsheetdialogfragment
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override public void onShow(DialogInterface dialogInterface) {
BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialogInterface;
FrameLayout bottomSheet = bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);
ViewGroup.LayoutParams layoutParams = bottomSheet.getLayoutParams();
// !!!
layoutParams.height = 900;
bottomSheet.setLayoutParams(layoutParams);
}
});
return dialog;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Make the bottom sheet non drag-able.
setStyle(DialogFragment.STYLE_NORMAL, R.style.BottomSheetDialogStyle);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.bottom_sheet_layout, container,
false);
// get the views and attach the listener
return view;
}
}
I was wondering, if we were using BottomSheetDialogFragment, is there a way to achieve
- A non-blocking bottom sheet. When we tap on non-bottom sheet item, the tapped item will get focus and bottom sheet will hide.
As you can see, when I tap on EditText region, the bottom sheet is hidden. But, the EditText is not getting focus.
Here's the complete workable demo for testing purpose - https://github.com/yccheok/wediary-sandbox/tree/master/bottom-sheet
Thank you.


