防止在外面触摸时解雇BottomSheetDialogFragment

Ram*_*hDR 18 android bottom-sheet

我已经实现了一个BottomSheet对话框,我希望当用户在偷看时(未完全展开状态)触摸底部外面时防止底片消失.

我已经设置dialog.setCanceledOnTouchOutside(false);了代码,但它似乎没有任何影响.

这是我的BottomSheetDialogFragment类:

public class ShoppingCartBottomSheetFragment extends BottomSheetDialogFragment  {

    private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {

        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                dismiss();
            }

        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
        }
    };

    @Override
    public void setupDialog(Dialog dialog, int style) {
        super.setupDialog(dialog, style);

        View contentView = View.inflate(getContext(), R.layout.fragment_shopping_cart_bottom_sheet, null);

        dialog.setCanceledOnTouchOutside(false);

        dialog.setContentView(contentView);

        CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
        CoordinatorLayout.Behavior behavior = params.getBehavior();

        if( behavior != null && behavior instanceof BottomSheetBehavior ) {
            ((BottomSheetBehavior) behavior).setBottomSheetCallback(mBottomSheetBehaviorCallback);
            ((BottomSheetBehavior) behavior).setPeekHeight(97);
            ((BottomSheetBehavior) behavior).setHideable(false);
        }
    }


    @Override
    public void onStart() {
        super.onStart();
        Window window = getDialog().getWindow();
        WindowManager.LayoutParams windowParams = window.getAttributes();
        windowParams.dimAmount = 0;
        windowParams.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
        window.setAttributes(windowParams);
    }
}
Run Code Online (Sandbox Code Playgroud)

根据BottomSheet 规范,底板可以通过触摸底板外部来解散,因此我有什么选择来覆盖这种行为并防止它被解雇?

M. *_*aei 23

您应该#setCancelable(false)在创建它的实例时使用.

    BottomSheetDialogFragment bottomSheetDialogFragment = new SequenceControlFragmentBottomSheet();
    bottomSheetDialogFragment.setCancelable(false);
    bottomSheetDialogFragment.show(getChildFragmentManager(), bottomSheetDialogFragment.getTag());
Run Code Online (Sandbox Code Playgroud)

  • 这不起作用,向下滚动或触摸底页外时它会被忽略 (2认同)

小智 20

在简单的底部表单对话框的情况下,上述所有答案都有点复杂,请使用可取消,因为它可以防止在对话框外滚动和单击。

mBottomSheetDialog.setCancelable(false)
Run Code Online (Sandbox Code Playgroud)
mBottomSheetDialog.setCanceledOnTouchOutside(false)
Run Code Online (Sandbox Code Playgroud)

只需将它用于简单的底部工作表对话框。它对我有用。


shi*_*ijo 12

setCancelable(false)也会阻止底板在背压时解除.如果我们在android设计支持库中查看底部工作表的布局资源,则会有一个带ID 的View组件,touch_outside并且OnClickListener在方法wrapInBottomSheet中有一个set,BottomSheetDialog用于检测外部的点击并关闭对话框.因此,为防止在底部板外触摸取消,我们需要删除OnClickListener.

将这些行添加到onActivityCreated方法(或之后的任何其他生命周期方法onCreateView).

@Override public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    View touchOutsideView = getDialog().getWindow()
        .getDecorView()
        .findViewById(android.support.design.R.id.touch_outside);
    touchOutsideView.setOnClickListener(null);
}
Run Code Online (Sandbox Code Playgroud)

此外,如果要通过向下滑动来防止底部页面关闭,请更改底部工作表对话框行为可隐藏的错误.为了setHideable(false)下面的代码添加到onCreateDialog方法.

@Override public Dialog onCreateDialog(Bundle savedInstanceState) {
    final BottomSheetDialog bottomSheetDialog =
        (BottomSheetDialog) super.onCreateDialog(savedInstanceState);

    bottomSheetDialog.setOnShowListener(new DialogInterface.OnShowListener() {
      @Override public void onShow(DialogInterface dialog) {
        FrameLayout bottomSheet =
        bottomSheetDialog.findViewById(android.support.design.R.id.design_bottom_sheet);

        if (null != bottomSheet) {
          BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
        behavior.setHideable(false);
        }
      }
    });
    return bottomSheetDialog;
  }
Run Code Online (Sandbox Code Playgroud)

  • 另见 https://medium.com/@betakuang/make-your-bottomsheetdialog-noncancelable-e50a070cdf07。对于 AndroidX,使用`com.google.android.material.R.id.design_bottom_sheet`(我没有测试)。 (3认同)
  • 对于 AndroidX,您需要获取的是“com.google.android.material.R.id.touch_outside”,而不是“design_bottom_sheet” (2认同)

Mar*_*rty 6

最简单的方法是setCanceledOnTouchOutside在BottomSheetDialogFragment 的对话框中设置为false。与科特林,

class XFragment : BottomSheetDialogFragment() {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        dialog?.setCanceledOnTouchOutside(false)
    }

}
Run Code Online (Sandbox Code Playgroud)