Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable dragging of BottomSheetDialogFragment with scrollable children

Is it possible to disable dragging for a BottomSheetDialogFragment, containing scrollable views such as a ViewPager or a NestedScrollView, such that it can't be dragged neither up nor down but still be dismissed by touching outside and that the children can be dragged anyways?

I've looked at all the answers here but I am not pleased since most don't take into account scrollable children or work by forcing the expanded state. The closest is this answer but nonetheless allows dragging the sheet up.

Is there any solution or at least guidance at what should I modify of the original source code?

like image 414
OneEyeQuestion Avatar asked Jan 20 '18 19:01

OneEyeQuestion


People also ask

How do I disable BottomSheetDialogFragment dragging?

Disable drag of BottomSheetDialogFragment Even if we have made the BottomSheetDialogFragment as expanded, user can hold the top part of the BottomSheet and drag to show peek view. It can also be disabled by overriding onStateChanged() . This will set the expanded state even if user drags the view.

How do I stop my bottom sheet from closing?

You should use #setCancelable(false) when you create an instance of it. Save this answer. Show activity on this post. setCancelable(false) will prevent the bottom sheet dismiss on back press also.

What is bottom sheet behavior?

Android Bottom Sheet is a component that slides up from the bottom of the screen having multiple options. Here are the examples of the Bottom sheet from apps. There are two types of bottom sheets, Persistent Bottom Sheet and Modal Bottom Sheet.

What is BottomSheetDialogFragment?

↳ com.google.android.material.bottomsheet.BottomSheetDialogFragment. Modal bottom sheet. This is a version of DialogFragment that shows a bottom sheet using BottomSheetDialog instead of a floating dialog.


1 Answers

If you debug your application and use Layout Inspector tool, you will see that BottomSheetDialogFragment uses CoordinatorLayout. Dimmed background is a simple view with an OnClickListener that closes the dialog, and sheet movement is driven by CoordinatorLayout.Behavior.

This can be overriden by modifying created dialog:

Java:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    final Dialog d = super.onCreateDialog(savedInstanceState);
    // view hierarchy is inflated after dialog is shown
    d.setOnShowListener(new DialogInterface.OnShowListener() {
        @Override
        public void onShow(DialogInterface dialogInterface) {
            //this disables outside touch
            d.getWindow().findViewById(R.id.touch_outside).setOnClickListener(null);
            //this prevents dragging behavior
            View content = d.getWindow().findViewById(R.id.design_bottom_sheet);
            ((CoordinatorLayout.LayoutParams) content.getLayoutParams()).setBehavior(null);
        }
    });
    return d;
}

Kotlin:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    val d = super.onCreateDialog(savedInstanceState)
    //view hierarchy is inflated after dialog is shown
    d.setOnShowListener {
        //this disables outside touch
        d.window.findViewById<View>(R.id.touch_outside).setOnClickListener(null)
        //this prevents dragging behavior
        (d.window.findViewById<View>(R.id.design_bottom_sheet).layoutParams as CoordinatorLayout.LayoutParams).behavior = null
    }
    return d
}

This does use internal IDs of design library, but unless for some reason they're changed this should be stable.

like image 175
Pawel Avatar answered Oct 06 '22 23:10

Pawel