How do you set the state of a fragment extending BottomSheetDialogFragment
to expanded using BottomSheetBehavior#setState(STATE_EXPANDED)
using the
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
setOnShowListener {
(this@TipsBottomDialogFragment.dialog as BottomSheetDialog).behavior.setState(
BottomSheetBehavior.STATE_EXPANDED
)
}
}
}
I think those above is better. Sadly I did not find those solution before I had solved. But write my solution. quite similar to all.
==================================================================================
I face the same issue. This is what I solved. The Behavior is hidden in BottomSheetDialog, which is available to get the behavior If you would like not to change your parent layout to be CooridateLayout, you can try this.
STEP 1: customize the BottomSheetDialogFragment
open class CBottomSheetDialogFragment : BottomSheetDialogFragment() {
//wanna get the bottomSheetDialog
protected lateinit var dialog : BottomSheetDialog
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
return dialog
}
//set the behavior here
fun setFullScreen(){
dialog.behavior.state = STATE_EXPANDED
}
}
STEP 2: make your fragment extend this customized fragment
class YourBottomSheetFragment : CBottomSheetDialogFragment(){
//make sure invoke this method after view is built
//such as after OnActivityCreated(savedInstanceState: Bundle?)
override fun onStart() {
super.onStart()
setFullScreen()//initiated at onActivityCreated(), onStart()
}
}
Posting this here to future readers, as I think know we can use another solution.
I was trying to solve the same problem you described with a BottomSheetDialog
.
I don't like using internal Android ids and I've just found there's a method inside BottomSheetDialog
getBehavior
that you can use:
You can use this inside your BottomSheetDialog
:
behavior.state = BottomSheetBehavior.STATE_EXPANDED
Using BottomSheetDialogFragment
you can do the same casting the dialog from that DialogFragment to BottomSheetDialog
.
"Note that you cannot call the method before view layouts."
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 laid 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:
// This listener's onShow is fired when the dialog is shown
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
// In a previous life I used this method to get handles to the positive and negative buttons
// of a dialog in order to change their Typeface. Good ol' days.
BottomSheetDialog d = (BottomSheetDialog) dialog;
// This is gotten directly from the source of BottomSheetDialog
// in the wrapInBottomSheet() method
FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
// Right here!
BottomSheetBehavior.from(bottomSheet)
.setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
In my case, my custom BottomSheet
turned out to be:
@SuppressWarnings("ConstantConditions")
public class ShareBottomSheetFragment extends AppCompatDialogFragment {
@NonNull @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
BottomSheetDialog dialog =
new BottomSheetDialog(getActivity(), R.style.Haute_Dialog_ShareImage);
dialog.setContentView(R.layout.dialog_share_image);
dialog.findViewById(R.id.cancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
SwitchCompat switchview = (SwitchCompat) dialog.findViewById(R.id.switchview);
switchview.setTypeface(FontCache.get(dialog.getContext(), lookup(muli, NORMAL)));
return dialog;
}
}
Let me know if this helps.
UPDATE
Note that you can also override BottomSheetDialogFragment
as:
public class SimpleInitiallyExpandedBottomSheetFragment extends BottomSheetDialogFragment {
@NonNull @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
// Do something with your dialog like setContentView() or whatever
return dialog;
}
}
But I really dont see why anyone would want to do that as the base BottomSheetFragment
doesn't do anything other than return a BottomSheetDialog
.
UPDATE FOR ANDROIDX
When using AndroidX, the resource previously found at android.support.design.R.id.design_bottom_sheet
can now be found at com.google.android.material.R.id.design_bottom_sheet
.
In your Kotlin BottomSheetDialogFragment class, override onCreateDialog as below
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val bottomSheetDialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
bottomSheetDialog.setOnShowListener {
val bottomSheet =
bottomSheetDialog.findViewById<FrameLayout>(
com.google.android.material.R.id.design_bottom_sheet
)
val behavior = BottomSheetBehavior.from(bottomSheet!!)
behavior.skipCollapsed = true
behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
return bottomSheetDialog
}
Apply BottomsheetDialogFragment
state in onResume
will solve this issue
@Override
public void onResume() {
super.onResume();
if(mBehavior!=null)
mBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
onShow(DialogInterface dialog)
and postDelayed
may cause animation glitch