BottomSheetDialogFragment Made Simpler
If this is the first time you are using BottomSheet in your android app then this the best place to get started.
What is Modal?
The idea is to put the user in a different ‘mode’ hence the name Modal. Also, the user can switch back to the previous mode at any time. In android, we use Dialogs as the base of modal windows.
What is BottomSheet?
In simple words, it's just another dialog with a different animation. Google has provided a subclass of Dialog calledBottomSheetDialog
that gives the required feel for a bottom sheet. You can use it as a Modal or Modal-bottom sheet. To use it you must add its dependency to your app’s build.gradle:
implementation 'com.google.android.material:material:1.0.0-beta01'
What is Persistent BottomSheet?
This lets you interact with not just a BottomSheet alone. This also uses a dialog underneath so none of your knowledge is gonna get wasted. But in addition to BottomSheetDialog
it uses a fragment that wraps the dialog inside it. One analogy for the persistent Bottom sheet is that it can save the state of the bottom sheet itself hence, the name persistent.
Only if you see
If you see the BottomSheetDialogFragment
class and its hierarchy you understand that it's based upon the same old fragments and uses BottomSheetDialog
. Yes, that’s all code it has.
Lifecycle
The lifecycle is no different than a fragment lifecycle. So does the implementation should be. One thing to remember here which again inherited from the DialogFragment is that a dialog is created before onCreateView
is called hence, you can use the dialog at onCreateView
.
onCreate->onCreateDialog-> onCreateView
Implementation
Now that I have covered how it works it should be easy to write an implementation on your own. You just need to extend BottomSheetDialogFragment
and override onCreateView
to return the view you want to show inside a BottomSheet:
class BottomSheetFragment : BottomSheetDialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.bottom_sheet, container,false)
}
If you are still looking for implementation you can see this for a well-explained example.
Tricks
You might be wondering how to make the BottomSheet.STATE_EXPANDED cover the full screen even if the content inside it isn’t enough to do so (by suppose using a NestedScrollingView with fillViewPort=”true”) because if you try to do so by behavior.state=BottomSheetBehavior.STATE_EXPANDED it won’t. This happens because the minimum height of the parent in which the inflated view resides need to be set equal to the height of the display itself. This can be done simply using:-
override fun onViewCreated(view: View, savedInstanceState: Bundle?){
dialog?.setOnShowListener { dialog ->
val d = dialog as BottomSheetDialog
val bottomSheetInternal =
d.findViewById<View>(R.id.design_bottom_sheet)
bottomSheetInternal?.minimumHeight=
Resources.getSystem().getDisplayMetrics().heightPixels
}
}
You can find the parent view of the Dialog if needed using the id
R.id.sheet_container
:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val view=inflater.inflate(R.layout.bottom_sheet, container, false)
parent=view.findViewById(R.id.sheet_container)
return view
}