BottomSheetDialogFragment - 如何设置展开高度(或最小顶部偏移)

问题描述 投票:36回答:3

我创建了一个BottomSheetDialogFragment,我想调整它的最大扩展高度。我怎样才能做到这一点?我可以找回BottomSheetBehaviour,但我能找到的只是一个用于窥视高度的二传手,但对于扩展的高度没什么。

public class DialogMediaDetails extends BottomSheetDialogFragment
{
    @Override
    public void setupDialog(Dialog dialog, int style)
    {
        super.setupDialog(dialog, style);
        View view = View.inflate(getContext(), R.layout.dialog_media_details, null);
        dialog.setContentView(view);

        ...

        View bottomSheet = dialog.findViewById(R.id.design_bottom_sheet);
        BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
        behavior.setPeekHeight(...);
        // how to set maximum expanded height???? Or a minimum top offset?

    }
}

编辑

我为什么需要那个?因为我在全屏活动中显示BottomSheet对话框,如果BottomSheet在顶部留下空间,它看起来很糟糕...

android android-support-library androiddesignsupport bottom-sheet
3个回答
20
投票

高度被包裹,因为膨胀的视图被添加到具有layout_height=wrap_content的FrameLayout。请参阅https://github.com/dandar3/android-support-design/blob/master/res/layout/design_bottom_sheet_dialog.xml上的FrameLayout(R.id.design_bottom_sheet)。

下面的类使得底部工作表全屏,背景透明并完全展开到顶部。

public class FullScreenBottomSheetDialogFragment extends BottomSheetDialogFragment {


    @CallSuper
    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ButterKnife.bind(this, view);
    }


    @Override
    public void onStart() {
        super.onStart();
        Dialog dialog = getDialog();

        if (dialog != null) {
            View bottomSheet = dialog.findViewById(R.id.design_bottom_sheet);
            bottomSheet.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
        }
        View view = getView();
        view.post(() -> {
            View parent = (View) view.getParent();
            CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) (parent).getLayoutParams();
            CoordinatorLayout.Behavior behavior = params.getBehavior();
            BottomSheetBehavior bottomSheetBehavior = (BottomSheetBehavior) behavior;
            bottomSheetBehavior.setPeekHeight(view.getMeasuredHeight());
            ((View)bottomSheet.getParent()).setBackgroundColor(Color.TRANSPARENT)

        });
    }

}

---编辑2018年8月30日---一年后我意识到背景是错误的。当用户拖动对话框时,这会将背景与内容一起拖动。我修复了它,以便底部工作表的父视图被着色。


13
投票

我找到了一个更简单的答案;在您的示例中,您使用此代码获取底部工作表的FrameLayout

View bottomSheet = dialog.findViewById(R.id.design_bottom_sheet);

然后,您可以将该视图的布局参数上的高度设置为您要将展开高度设置为的任何高度。

bottomSheet.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;

12
投票

大更新避免重复的代码我给full answer链接,在那里你可以找到有关如何获得谷歌地图等完整行为的所有解释。


我想调整它的最大扩展高度。我怎样才能做到这一点?

BottomSheetBottomSheetDialogFragment都使用了一个BottomSheetBehavior,你可以在支持库23.x中找到它。

该Java类对mMinOffset有两种不同的用途,其中一种用于定义它将用于绘制其内容的父项区域(可能是NestedScrollView)。另一个用途,如果你定义扩展的锚点,我的意思是,如果你向上滑动形式STATE_COLLAPSEDit将动画你的BottomSheetuntil他到达这个锚点,但如果你仍然可以保持向上滑动覆盖所有父高度(CoordiantorLayout高度)。

如果你看一下BottomSheetDialog,你会看到这个方法:

private View wrapInBottomSheet(int layoutResId, View view, ViewGroup.LayoutParams params) {
    final CoordinatorLayout coordinator = (CoordinatorLayout) View.inflate(getContext(),
            android.support.design.R.layout.design_bottom_sheet_dialog, null);
    if (layoutResId != 0 && view == null) {
        view = getLayoutInflater().inflate(layoutResId, coordinator, false);
    }
    FrameLayout bottomSheet = (FrameLayout) coordinator.findViewById(android.support.design.R.id.design_bottom_sheet);
    BottomSheetBehavior.from(bottomSheet).setBottomSheetCallback(mBottomSheetCallback);
    if (params == null) {
        bottomSheet.addView(view);
    } else {
        bottomSheet.addView(view, params);
    }
    // We treat the CoordinatorLayout as outside the dialog though it is technically inside
    if (shouldWindowCloseOnTouchOutside()) {
        final View finalView = view;
        coordinator.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (isShowing() &&
                        MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_UP &&
                        !coordinator.isPointInChildBounds(finalView,
                                (int) event.getX(), (int) event.getY())) {
                    cancel();
                    return true;
                }
                return false;
            }
        });
    }
    return coordinator;
}

不知道你想要哪两种行为,但如果你需要第二种行为,请遵循以下步骤:

  1. 创建一个Java类并从CoordinatorLayout.Behavior<V>扩展它
  2. 将粘贴代码从默认的BottomSheetBehavior文件复制到新文件。
  3. 使用以下代码修改方法clampViewPositionVertical@Override public int clampViewPositionVertical(View child, int top, int dy) { return constrain(top, mMinOffset, mHideable ? mParentHeight : mMaxOffset); } int constrain(int amount, int low, int high) { return amount < low ? low : (amount > high ? high : amount); }
  4. 添加新状态 public static final int STATE_ANCHOR_POINT = X;
  5. 修改下一个方法:onLayoutChildonStopNestedScrollBottomSheetBehavior<V> from(V view)setState(可选)

以下是它的外观: []

© www.soinside.com 2019 - 2024. All rights reserved.