如何为BottomSheetDialogFragment设置最大宽度

13
问题:
我正在使用 BottomSheetDialogFragment 作为我的模态底部表单,想要设置一个最大宽度,以便在平板电脑/大屏幕上,BottomSheet 不会占据整个屏幕的宽度。我该怎么处理这个问题?谢谢!
相关代码和资源:

fragment_bottomsheet.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/BottomSheetStyle">

    <GridLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:alignmentMode="alignBounds"
        android:columnOrderPreserved="false"
        android:columnCount="3"
        android:paddingTop="16dp"
        android:paddingBottom="8dp"
        android:paddingRight="8dp"
        android:paddingLeft="8dp"
        app:layout_behavior="android.support.design.widget.BottomSheetBehavior">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableTop="@drawable/image1"
            android:text="Open"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableTop="@drawable/image2"
            android:text="Save"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableTop="@drawable/image3"
            android:text="Send"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableTop="@drawable/image4"
            android:text="Upload"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableTop="@drawable/image5"
            android:text="Share"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:drawableTop="@drawable/iamge6"
            android:text="More"/>

    </GridLayout>

</android.support.design.widget.CoordinatorLayout>

res/values/styles.xml:

<style name="BottomSheetStyle">
    <item name="android:layout_height">match_parent</item>
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_gravity">center_horizontal</item>
</style>

res/values-w600dp/styles.xml:

<style name="BottomSheetStyle">
    <item name="android:layout_height">match_parent</item>
    <item name="android:layout_width">640dp</item>
    <item name="android:layout_gravity">center_horizontal</item>
</style>

你可以更改NestedScrollView的尺寸来更改BottomSheet的尺寸。 - Sagar Nayak
我的布局中没有使用NestedScrollView - ade.akinyede
5个回答

9
我发现了一个对我有效的解决方案:

我找到了一个解决方法,适用于我:

@Override
public void onResume() {
    super.onResume();

    // Resize bottom sheet dialog so it doesn't span the entire width past a particular measurement
    WindowManager wm = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    DisplayMetrics metrics = new DisplayMetrics();
    display.getMetrics(metrics);
    int width = metrics.widthPixels < 1280 ? metrics.widthPixels : 1280;
    int height = -1; // MATCH_PARENT
    getDialog().getWindow().setLayout(width, height);
}

基本上,这使我能够根据屏幕来动态指定我的BottomSheet的尺寸。

请注意,widthPixels 并不是衡量屏幕宽度的最佳方式,因为不同的屏幕具有不同的像素密度。最好检查 dp 而不是 px 中的宽度。请参阅下面的答案。 - jakub.g

7

以下是对 OP 答案的改进,考虑到设备的像素密度和方向:

public final class MyBottomSheetDialogFragment extends BottomSheetDialogFragment {
    ...

    private static int dpToPx(int dp) {
        // https://developer.android.com/guide/practices/screens_support.html#dips-pels
        float density = Resources.getSystem().getDisplayMetrics().density;
        return (int) ((dp * density) + 0.5f);
    }

    @Override
    public void onResume() {
        super.onResume();

        Configuration configuration = getActivity().getResources().getConfiguration();
        if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE &&
                configuration.screenWidthDp > 450) {
            // you can go more fancy and vary the bottom sheet width depending on the screen width
            // see recommendations on https://material.io/components/sheets-bottom#specs
            getDialog().getWindow().setLayout(ViewUtils.dpToPx(450), -1);
        }
    }
}

0

正如您所提到的,BottomSheetDialogFragment似乎不尊重“wrap_content”(即使它包含的所有视图的宽度都为“wrap_content”,它仍然始终匹配父级的宽度)。 我发现对我来说最好的解决方法是利用OnGlobalLayoutListener来监听适当的时间以调整宽度。 例如:

 @Override
public void setupDialog(final Dialog dialog, int style) {
    super.setupDialog(dialog, style);
    View v = View.inflate(getActivity(), R.layout.my_bottom_sheet, null);
    View viewWithGreatestWidth = v.findViewById(R.id.my_super_wide_view);
    // Your view setup code goes here ....

    if(getResources().getBoolean(R.bool.isTablet)) {
        v.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    v.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                } else {
                    v.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }

                // Can also just use your own preset "max width" value here;
                // This code just lets you fake "wrap_content" value
                getDialog().getWindow().setLayout(viewWithGreatestWidth.getMeasuredWidth(), WindowManager.LayoutParams.WRAP_CONTENT);
            }
        });
    }

    dialog.setContentView(v);
}

0

如果您想要纯粹使用xml来实现,您可以设置一个样式并使用android:maxWidth

例如:

<LinearLayout
   android:id="@+id/bottom_sheet"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:orientation="vertical"
   android:background="@color/white"
   app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
   style="@style/styleWithFixedWidth"
 >

并且在 styles.xml

<style name="styleWithFixedWidth">
  <item name="android:maxWidth">550dp</item>
</style>

0

这对于我在BottomSheetDialogFragment上有效。我能够使用以下代码设置最大宽度:

dialog.maxWidth = Resources.getSystem().displayMetrics.widthPixels

您可以在onCreateDialog函数中设置此项。此示例将底部表的宽度设置为显示器的宽度。

希望这可以帮助到您!


问题不在于填充宽度,而是设置最大宽度。 - ade.akinyede

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