【问题标题】:Android BottomSheetBehavior, how to disable snap?Android BottomSheetBehavior,如何禁用快照?
【发布时间】:2025-11-23 20:30:02
【问题描述】:

标准 android BottomSheetBehavior 具有树状态:隐藏、折叠和展开。

我想允许用户在折叠和展开之间“离开”底部工作表。现在,使用默认行为,它将根据最接近的折叠或展开对齐。我应该如何禁用此快照功能?

【问题讨论】:

    标签: android android-support-library bottom-sheet


    【解决方案1】:

    我将介绍一种方法来实现 View 扩展 BottomSheetDialogFragment 的此类功能。

    扩展:

    首先覆盖onResume:

    @Override
    public void onResume() {
        super.onResume();
        addGlobaLayoutListener(getView());
    }
    
    private void addGlobaLayoutListener(final View view) {
        view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                setPeekHeight(v.getMeasuredHeight());
                v.removeOnLayoutChangeListener(this);
            }
        });
    }
    
    public void setPeekHeight(int peekHeight) {
        BottomSheetBehavior behavior = getBottomSheetBehaviour();
        if (behavior == null) {
            return;
        }
        behavior.setPeekHeight(peekHeight);
    }
    

    上面的代码应该做的只是将BottomSheet peekHeight 设置为视图的高度。这里的关键是函数getBottomSheetBehaviour()。实现如下:

    private BottomSheetBehavior getBottomSheetBehaviour() {
        CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) ((View) getView().getParent()).getLayoutParams();
        CoordinatorLayout.Behavior behavior = layoutParams.getBehavior();
        if (behavior != null && behavior instanceof BottomSheetBehavior) {
            ((BottomSheetBehavior) behavior).setBottomSheetCallback(mBottomSheetBehaviorCallback);
            return (BottomSheetBehavior) behavior;
        }
        return null;
    }
    

    这只是检查View 的父级是否设置了“CoordinatorLayout.LayoutParams”。如果是,设置适当的BottomSheetBehavior.BottomSheetCallback(下一部分需要),更重要的是返回CoordinatorLayout.Behavior,它应该是BottomSheetBehavior

    正在折叠:

    这里的 [`BottomSheetBehavior.BottomSheetCallback.onSlide (View bottomSheet, float slideOffset)``](https://developer.android.com/reference/android/support/design/widget/BottomSheetBehavior.BottomSheetCallback.html#onSlide(android.view.View, float)) 正是我们所需要的。来自[文档](https://developer.android.com/reference/android/support/design/widget/BottomSheetBehavior.BottomSheetCallback.html#onSlide(android.view.View, float)):

    随着底部纸张向上移动,偏移量会增加。从 0 到 1 工作表处于折叠和展开状态之间,从 -1 到 0 处于隐藏和折叠状态之间。

    这意味着,折叠检测只需要检查第二个参数:

    在同一个类中定义BottomSheetBehavior.BottomSheetCallback

    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) {
            if (slideOffset < 0) {
                dismiss();
            }
        }
    };
    

    【讨论】: