How to disable BottomSheetDialogFragment dragging

后端 未结 14 1274
猫巷女王i
猫巷女王i 2021-01-31 04:58

How to disable BottomSheetDialogFragment dragging by finger?

I saw similar questions, but they\'re all about BottomSheet not BottomSheetD

相关标签:
14条回答
  • 2021-01-31 05:24

    Having created MyActivity as follows:

    public class MyActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_my);
    
            new MyBottomSheetFragment().show(getSupportFragmentManager(), "tag");
        }
    
        public static class MyBottomSheetFragment extends BottomSheetDialogFragment {
    
            @Override
            public void setupDialog(Dialog dialog, int style) {
                BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialog;
                bottomSheetDialog.setContentView(R.layout.sample);
    
                try {
                    Field behaviorField = bottomSheetDialog.getClass().getDeclaredField("behavior");
                    behaviorField.setAccessible(true);
                    final BottomSheetBehavior behavior = (BottomSheetBehavior) behaviorField.get(bottomSheetDialog);
                    behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
    
                        @Override
                        public void onStateChanged(@NonNull View bottomSheet, int newState) {
                            if (newState == BottomSheetBehavior.STATE_DRAGGING{ 
                                behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                            }
                        }
    
                        @Override
                        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                        }
                    });
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    Where R.layout.sample is a simple layout:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    
        <View
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="#e479da" />
    
        <View
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="#798de4" />
    
        <View
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="#e4db79" />
    
    </LinearLayout>
    

    You'll get following output:

    A part of solution is borrowed from this answer.

    0 讨论(0)
  • 2021-01-31 05:29

    There is simpler way of achieving the same after material design 1.2.0 was released.

    https://developer.android.com/reference/com/google/android/material/bottomsheet/BottomSheetBehavior#setdraggable

    When calling from BottomSheetDialogFragment:

        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)
    
                if (bottomSheet != null) {
                    val behavior: BottomSheetBehavior<*> = BottomSheetBehavior.from(bottomSheet)
                    behavior.isDraggable = false
                }
            }
            return bottomSheetDialog
        }
    

    Or with styling:

        <style name="SomeStyle" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
            <item name="behavior_draggable">false</item>
        </style>
    

    And then in onCreate of your dialog fragment:

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setStyle(DialogFragment.STYLE_NORMAL, R.style.SomeStyle)
        }
    
    0 讨论(0)
  • 2021-01-31 05:33

    This is how I managed to fix it:

    mBehavior = BottomSheetBehavior.from((View) rootView.getParent());
    mBehavior.setHideable(false);
    
    0 讨论(0)
  • 2021-01-31 05:33

    Too late but worth to share.

      behavior.setDraggable(false)
    

    This line did the job.

    0 讨论(0)
  • 2021-01-31 05:34

    Just Add bottomSheetBehavior.setHideable(false);

    You can get Object of BottomshitBehaviour in BottomshitDialogFragment.

     CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) view.getParent()).getLayoutParams();
                CoordinatorLayout.Behavior behavior = params.getBehavior();
                View parent = (View) view.getParent();
                getHeight(view);
                ((BottomSheetBehavior) behavior).setFitToContents(true);
                BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(parent);
    bottomSheetBehavior.setHideable(false);
    
    0 讨论(0)
  • Top rated answer contains boilerplate code such as Field and try-catches.

    So here is a better version of it in Kotlin:

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return super.onCreateDialog(savedInstanceState).apply {
            setOnShowListener(::onShow)
        }
    }
    
    private fun onShow(dialogInterface: DialogInterface) {
        val dialog = dialogInterface as BottomSheetDialog
        val frameLayout =
            dialog.findViewById<FrameLayout>(com.google.android.material.R.id.design_bottom_sheet)
                ?: return
    
        BottomSheetBehavior.from(frameLayout).apply {
            addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
                override fun onStateChanged(bottomSheet: View, newState: Int) {
                    if (newState == BottomSheetBehavior.STATE_DRAGGING)
                        state = BottomSheetBehavior.STATE_EXPANDED
                }
    
                override fun onSlide(bottomSheet: View, slideOffset: Float) = Unit
            })
        }
    }
    

    Use it in BottomSheetDialogFragment

    0 讨论(0)
提交回复
热议问题