禁用具有可滚动子项的BottomSheetDialogFragment的拖动功能

8

有没有可能禁用BottomSheetDialogFragment的拖动功能,其中包含可滚动的视图,如ViewPagerNestedScrollView,使其既不能向上也不能向下拖动,但仍然可以通过触摸外部来关闭,并且子视图仍然可以被拖动?

我已经查看了所有答案这里,但我并不满意,因为大多数答案都没有考虑到可滚动的子视图,或者通过强制扩展状态来工作。最接近的是这个答案,但仍然允许向上拖动该表。

是否有任何解决方案,或者至少指导我应该修改原始源代码的哪些部分?

1个回答

18
如果您调试应用程序并使用布局检查器工具,您将看到BottomSheetDialogFragment使用CoordinatorLayout。昏暗的背景是一个带有OnClickListener的简单视图,它关闭对话框,而片移动则由CoordinatorLayout.Behavior驱动。
这可以通过修改创建的对话框来覆盖: 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
}

这确实使用了设计库的内部ID,但除非由于某种原因它们被更改,否则应该是稳定的。


我在编辑我的问题时出现了错误。抱歉。我仍然希望能够通过点击来解除。无论如何,您提出的方案是否也会消除潜在子项的拖动? - OneEyeQuestion
我刚刚测试了你的解决方案,但是底部表单没有展开到覆盖整个屏幕的行为。我尝试使用peek height,但是没有起作用。你是如何控制初始高度的? - OneEyeQuestion
2
你可以覆盖R.id.design_bottom_sheet的更多布局参数,包括底部重力和wrap_content的布局高度,但此时我开始想知道是否应该创建一个带有底部重力和滑入/滑出动画的常规DialogFragment,因为你没有使用Sheet的核心功能,即嵌套滚动、拖动和捕捉。 - Pawel
如果在 Material Comp. v1.1.0-alpha10 中调用 dismiss(),则会抛出 IllegalArgumentException - Jemshit Iskenderov
@JemshitIskenderov 我不确定这是否可以被视为一个 bug,因为它似乎只是强制检查底部表单是否具有有效的行为。所以它显然不会考虑到删除行为对象的这种“hack”。我认为在这一点上,我们需要用一个自定义的 BottomSheetBehavior 来替换它,该行为不处理/拦截触摸事件。 - Pawel
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接