如何允许BottomSheetDialog的外部触摸?

Anm*_*mol 7 android fragment bottom-sheet

我正在BottomSheetDialogFragment满足我的要求是创建底部菜单,如果我在片段区域外单击,则不应取消对话框并应保留。

问题: 片段外的事件应传播到较低的片段视图/片段。

我已经在下面尝试过(不适用于BottomDialogFragment): Allow external touch for DialogFragment

要停止对话框中取消我尝试下面(我称之为setCancelable(boolean)onStart()BottomDialogFragment的):

@Override
    public void setCancelable(boolean cancelable) {
        super.setCancelable(cancelable);

        BottomSheetDialog dialog = (BottomSheetDialog) getDialog();
        dialog.setCanceledOnTouchOutside(cancelable);

        View bottomSheetView = dialog.getWindow().getDecorView().findViewById(R.id.design_bottom_sheet);
        BottomSheetBehavior.from(bottomSheetView).setHideable(cancelable);
    }
Run Code Online (Sandbox Code Playgroud)

参考

编辑:发现它很难,没有其他方法然后使用坐标布局。BottomSheetDialog 的最佳解决方案是here

  • 这个解决方案解决了这个问题,但又带来了一个问题。即所有其他应用程序事件都没有导航所有 actionMode 事件。
  • 这是我对问题的最佳解决方案

Yar*_*nko 5

在您的以下代码中尝试BottomSheetDialog

 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
     return (super.onCreateDialog(savedInstanceState) as BottomSheetDialog).apply {
         setCanceledOnTouchOutside(false)
     }
 }
Run Code Online (Sandbox Code Playgroud)

或通过<CoordinatorLayout> 例如您的<ConstraintLayout>和实现<layout />并附加到BottomSheetBehavior.

  • 尽量不使用对话框。只需包含 `&lt;layout /&gt;` 并附加到 `BottomSheetBehavior`,它就可以正常工作。 (2认同)

Sam*_*ekl 5

正如 Pankaj Kumar 所说,默认情况下这是不可能的。但是,我找到了一种可行的解决方法,允许触摸底部工作表外部的视图,同时保持底部工作表打开

您可以覆盖类似的布局BottomSheetDialog

值/refs.xml

<resources xmlns:tools="http://schemas.android.com/tools">
    <item name="design_bottom_sheet_dialog" type="layout" tools:override="true">@layout/custom_design_bottom_sheet_dialog</item>
</resources>
Run Code Online (Sandbox Code Playgroud)

布局/custom_design_bottom_sheet_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ This is an override of the design_bottom_sheet_dialog from material library
-->
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

  <androidx.coordinatorlayout.widget.CoordinatorLayout
      android:id="@+id/coordinator"
      android:layout_width="match_parent"
      android:layout_height="wrap_content">

    <View
        android:id="@+id/touch_outside"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:visibility="gone"
        android:importantForAccessibility="no"
        android:soundEffectsEnabled="false"
        tools:ignore="UnusedAttribute"/>

    <FrameLayout
        android:id="@+id/design_bottom_sheet"
        style="?attr/bottomSheetStyle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|top"
        app:layout_behavior="@string/bottom_sheet_behavior"/>

  </androidx.coordinatorlayout.widget.CoordinatorLayout>

</FrameLayout>
Run Code Online (Sandbox Code Playgroud)

YourCustomBottomSheetDialogFragment

override fun onStart() {
        super.onStart()

        // Set layout for custom bottom sheet by allowing background touches
        dialog?.window?.apply {
            setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
            setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)
            
            attributes = attributes.apply {
                gravity = Gravity.BOTTOM
            }
            setDimAmount(0.0f)
        }
    }
Run Code Online (Sandbox Code Playgroud)

通过这样做,对话框具有wrap_content高度,并且标志允许由该对话框外部的视图处理触摸

  • 很好,但它会影响所有底部表单对话框。有什么方法可以仅针对一个特定的底页进行此更改吗? (3认同)

moh*_*sen 2

你应该使用android.support.design.widget.BottomSheetBehavior.

bottomSheet但如果你想在其他课程中使用,我建议你使用 aFragment并在此fragment打开你的bottomSheet

以这种方式打开你的片段。

在您的片段中,bottomSheet使用以下代码打开您的片段:

onInitViews

var mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheetCoordinatorLayout)
mBottomSheetBehavior!!.state = BottomSheetBehavior.STATE_HIDDEN

mBottomSheetBehavior!!.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
     override fun onStateChanged(bottomSheet: View, newState: Int) {
          when (newState) {
             BottomSheetBehavior.STATE_HIDDEN -> {
                  fragmentManager?.popBackStack()
             }
             //BottomSheetBehavior.STATE_COLLAPSED -> "Collapsed"
             //BottomSheetBehavior.STATE_DRAGGING -> "Dragging..."
             //BottomSheetBehavior.STATE_EXPANDED -> "Expanded"
             //BottomSheetBehavior.STATE_SETTLING -> "Settling..."
           }
      }

      override fun onSlide(bottomSheet: View, slideOffset: Float) {
          //text_view_state!!.text = "Sliding..."
      }
})
Run Code Online (Sandbox Code Playgroud)

你的layout应该是这样的:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layoutDirection="ltr">

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/bottomSheetCoordinatorLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:behavior_hideable="true"
        app:behavior_peekHeight="55dp"
        app:layout_behavior="@string/bottom_sheet_behavior">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/top_radius_primary_color"
            android:paddingStart="@dimen/material_size_32"
            android:paddingEnd="@dimen/material_size_32">

        </RelativeLayout>
    </android.support.design.widget.CoordinatorLayout>
</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)

我希望它能帮助你