2016-07-18 2 views
4

ВопросКак установить максимальную ширину для BottomSheetDialogFragment

Я использую 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> 

Рез/значения/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> 

Рез/значения-w600 дп/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> 
+0

можно изменить размеры nestedscrollview изменить размеры bottomsheet. –

+0

Я не использую 'NestedScrollView' в своем макете. –

ответ

3

Я нашел решение, которое работает для меня:

@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 основанные на дисплее.

+0

Обратите внимание, что 'widthPixels' - это не самый лучший способ измерения ширины экрана, поскольку разные экраны имеют разную плотность пикселей. Лучше проверить ширину в 'dp' вместо' px'. См. Мой ответ ниже. –

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

Вариант ответа ОП, что учитывает плотность рассмотрения устройства пикселей и ориентации:

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/guidelines/components/bottom-sheets.html#bottom-sheets-specs 
      getDialog().getWindow().setLayout(ViewUtils.dpToPx(450), -1); 
     } 
    } 
} 
Смежные вопросы