Search code examples
androidandroid-support-librarybottom-sheetandroid-support-design

Disabling User dragging on BottomSheet


I am trying to disable user dragging on BottomSheet. The reason I want to disable is two things. 1. It's preventing the ListView from scrolling downward, 2. I don't want users to dismiss using dragging but with a button on the BottomSheetView. This is what I've done

 bottomSheetBehavior = BottomSheetBehavior.from(bottomAnc);
    bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            if (newState == BottomSheetBehavior.STATE_EXPANDED) {
                //Log.e("BottomSheet", "Expanded");
            } else if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
                //Log.e("BottomSheet", "Collapsed");
            }
        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
            // React to dragging events
            bottomSheet.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    int action = MotionEventCompat.getActionMasked(event);
                    switch (action) {
                        case MotionEvent.ACTION_DOWN:
                            return false;
                        default:
                            return true;
                    }
                }
            });
        }
    });

The bottomSheetLayout

    <?xml version="1.0" encoding="utf-8"?><FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="@string/bottom_sheet_behavior"
android:id="@+id/bottomSheet">

<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:elevation="10dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="center_vertical">

            <TextView
                android:id="@+id/text1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Order Items"
                android:layout_margin="16dp"
                android:textAppearance="@android:style/TextAppearance.Large"/>


            <Button
                android:layout_width="50dp"
                android:layout_height="wrap_content"
                android:layout_marginRight="5dp"
                android:background="@drawable/bg_accept"/>

            <Button
                android:layout_width="50dp"
                android:layout_height="wrap_content"
                android:layout_marginRight="8dp"
                android:background="@drawable/bg_cancel"/>

        </LinearLayout>

        <ListView
            android:id="@+id/item_edit"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white"
            android:divider="@color/md_divider_black"
            android:dividerHeight="1dp"/>

    </LinearLayout>

</android.support.v7.widget.CardView>


Solution

  • It can be now no longer relevant, but I will leave it here:

    import android.content.Context
    import android.util.AttributeSet
    import androidx.coordinatorlayout.widget.CoordinatorLayout
    import android.view.MotionEvent
    import android.view.View
    import com.google.android.material.bottomsheet.BottomSheetBehavior
    
    @Suppress("unused")
    class LockableBottomSheetBehavior<V : View> : BottomSheetBehavior<V> {
        constructor() : super()
        constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    
        var swipeEnabled = true
    
        override fun onInterceptTouchEvent(
            parent: CoordinatorLayout,
            child: V,
            event: MotionEvent
        ): Boolean {
            return if (swipeEnabled) {
                super.onInterceptTouchEvent(parent, child, event)
            } else {
                false
            }
        }
    
        override fun onTouchEvent(parent: CoordinatorLayout, child: V, event: MotionEvent): Boolean {
            return if (swipeEnabled) {
                super.onTouchEvent(parent, child, event)
            } else {
                false
            }
        }
    
        override fun onStartNestedScroll(
            coordinatorLayout: CoordinatorLayout,
            child: V,
            directTargetChild: View,
            target: View,
            axes: Int,
            type: Int
        ): Boolean {
            return if (swipeEnabled) {
                super.onStartNestedScroll(
                    coordinatorLayout,
                    child,
                    directTargetChild,
                    target,
                    axes,
                    type
                )
            } else {
                false
            }
        }
    
        override fun onNestedPreScroll(
            coordinatorLayout: CoordinatorLayout,
            child: V,
            target: View,
            dx: Int,
            dy: Int,
            consumed: IntArray,
            type: Int
        ) {
            if (swipeEnabled) {
                super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
            }
        }
    
        override fun onStopNestedScroll(
            coordinatorLayout: CoordinatorLayout,
            child: V,
            target: View,
            type: Int
        ) {
            if (swipeEnabled) {
                super.onStopNestedScroll(coordinatorLayout, child, target, type)
            }
        }
    
        override fun onNestedPreFling(
            coordinatorLayout: CoordinatorLayout,
            child: V,
            target: View,
            velocityX: Float,
            velocityY: Float
        ): Boolean {
            return if (swipeEnabled) {
                super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY)
            } else {
                false
            }
        }
    }
    

    And use it in your xml file:

    app:layout_behavior="com.your.package.LockableBottomSheetBehavior"
    

    It disables all users actions, it can be used when you want control BottomSheet only programmatically.