How do you set the state of a fragment extending BottomSheetDialogFragment
to expanded using BottomSheetBehavior#setState(STATE_EXPANDED)
using the Android Support Design Library (v23.2.1)?
https://code.google.com/p/android/issues/detail?id=202396 says:
Bottom sheets are set to STATE_COLLAPSED at first. Call BottomSheetBehavior#setState(STATE_EXPANDED) if you want to expand it. Note that you cannot call the method before view layouts.
The suggested practice requires a view to be inflated first, but I'm not sure how I'll set the BottomSheetBehaviour onto a fragment (BottomSheetDialogFragment
).
View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
Apply BottomsheetDialogFragment state in OnResume will solve this issue
onShow(DialogInterface dialog) and postDelayed may cause animation glitch
I met NullPointException in
BottomSheetBehavior.from(bottomSheet)
becaused.findViewById(android.support.design.R.id.design_bottom_sheet)
returns null.It's strange. I add this line of code to Watches in Android Monitor in DEBUG mode and found it return Framelayout normally.
Here's code of
wrapInBottomSheet
in BottomSheetDialog:Occasionally, I found that
R.id.design_bottom_sheet
is not equal toandroid.support.design.R.id.design_bottom_sheet
. They have different value in different R.java.So I change
android.support.design.R.id.design_bottom_sheet
toR.id.design_bottom_sheet
.No more NullPointException now.
The above text is the clue.
Dialogs have a listener that is fired once the dialog is shown. The dialog cannot be shown if it isn't layed out.
So, in the
onCreateDialog()
of your modal bottom sheet (BottomSheetFragment
), just before returning the dialog (or anywhere, once you have a reference to the dialog), call:In my case, my custom
BottomSheet
turned out to be:Let me know if this helps.
UPDATE
Note that you can also override
BottomSheetDialogFragment
as:But I really dont see why anyone would want to do that as the base
BottomSheetFragment
doesn't do anything other than return aBottomSheetDialog
.UPDATE FOR ANDROIDX
When using AndroidX, the resource previously found at
android.support.design.R.id.design_bottom_sheet
can now be found atcom.google.android.material.R.id.design_bottom_sheet
.efeturi's answer is great, however, if you want to use onCreateView() to create your BottomSheet, as opposed to going with onCreateDialog(), here is the code you will need to add under your onCreateView() method:
All results with using onShow() cause random render bug when soft keyboard is displayed. See screenshot bellow - BottomSheet dialog is not at bottom of screen but is placed like keyboard was displayed. This problem is not occurs always but quite often.
UPDATE
My solution with reflection of private member is unnecessary. Using postDelayed (with about 100 ms) for creating and showing dialog after hide soft keyboard is better solution. Then the above solutions with onShow() are ok.
So I implement other solution, but it requires using reflection, because BottomSheetDialog has all members as private. But it solves render bug. BottomSheetDialogFragment class is only AppCompatDialogFragment with onCreateDialog method which create BottomSheetDialog. I create own child of AppCompatDialogFragment which create my class extends BottomSheetDialog and which solves access to private behavior member and set it in onStart method to STATE_EXPANDED state.
The easiest way I implemented is as below, Here we are finding android.support.design.R.id.design_bottom_sheet and setting bottom sheet state as EXPANDED.
Without this, my bottom sheet was always stuck in the COLLAPSED state if view height is more than 0.5 of screen height and I have to manually scroll to view full bottom sheet.