Android BottomSheetDialogFragment не расширяется полностью

у меня есть следующая реализация нижнего листа теста.

когда я устанавливаю peekHeight в значение меньше 500, он работает. После некоторого значения любое увеличение высоты взгляда не изменит способ расширения нижнего листа. Он просто остается там, чтобы только перетащить вручную. Как мы устанавливаем peekHeight программно, чтобы гарантировать, что нижний лист автоматически расширен до peek высота.

enter image description here

bottom_sheet_dialog_main

<?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"
    android:id="@+id/locUXCoordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:id="@+id/locUXView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        android:orientation="vertical"
        app:behavior_hideable="false"
        app:behavior_peekHeight="0dp"
        app:layout_behavior="@string/bottom_sheet_behavior">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="1 Value" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="2 Value" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="3 Value" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="4 Value" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="5 Value" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="6 Value" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="7 Value" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="8 Value" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="9 Value" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:text="First Value" />
    </LinearLayout>
</android.support.design.widget.CoordinatorLayout>

Java-код

public class MyBottomSheetDialogFragment extends BottomSheetDialogFragment {

    private static BottomSheetBehavior bottomSheetBehavior;
    private static View bottomSheetInternal;
    private static MyBottomSheetDialogFragment INSTANCE;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialog) {
                BottomSheetDialog d = (BottomSheetDialog) dialog;
                CoordinatorLayout coordinatorLayout = (CoordinatorLayout)d.findViewById(R.id.locUXCoordinatorLayout);
                bottomSheetInternal = d.findViewById(R.id.locUXView);
                bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetInternal);
                bottomSheetBehavior.setPeekHeight(bottomSheetInternal.getHeight());
                bottomSheetInternal.requestLayout();
                coordinatorLayout.getLayoutParams().height = bottomSheetInternal.getHeight();
                Toast.makeText(getActivity(), "Height is" + bottomSheetInternal.getHeight() + "  " + coordinatorLayout.getLayoutParams().height, Toast.LENGTH_LONG).show();

            }
        });
        INSTANCE = this;
        return inflater.inflate(R.layout.bottom_sheet_dialog_main, container, false);
    }
}

3 ответов


Я нашел другое решение. Может быть, для будущих читателей это будет полезно.

@Override
public void setupDialog(Dialog dialog, int style) {
    super.setupDialog(dialog, style);
    final View root = View.inflate(getContext(), R.layout.fragment_bottom_sheet_choose_time, null);
    dialog.setContentView(root);
    initView(root);

    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) root.getParent()).getLayoutParams();
    CoordinatorLayout.Behavior behavior = params.getBehavior();

    if (behavior != null && behavior instanceof BottomSheetBehavior) {
        mBottomSheetBehavior = (BottomSheetBehavior) behavior;
        mBottomSheetBehavior.setBottomSheetCallback(mBottomSheetBehaviorCallback);

        root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                root.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                int height = root.getMeasuredHeight();
                mBottomSheetBehavior.setPeekHeight(height);
            }
        });
    }
}

как упоминал @Anthonyeef, здесь ViewTreeObserver предназначен для получения точной высоты измерения после того, как вид действительно измеряется и GlobalOnLayoutListener удаляется для повышения производительности.

но, пожалуйста, перед использованием в производстве, протестируйте это решение на разных устройствах и экранах, потому что если ваш контент в нижнем листе выше, чем ваш экран, он может произвести некоторые странные салфетки поведение.


используя этот код в onCreateView.

getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
        @Override
        public void onShow(DialogInterface dialog) {
            BottomSheetDialog d = (BottomSheetDialog) dialog;
            FrameLayout bottomSheet = (FrameLayout) d.findViewById(R.id.design_bottom_sheet);
            CoordinatorLayout coordinatorLayout = (CoordinatorLayout) bottomSheet.getParent();
            BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
            bottomSheetBehavior.setPeekHeight(bottomSheet.getHeight());
            coordinatorLayout.getParent().requestLayout();
        }
    });

при более глубоком осмотре пользовательского интерфейса мы обнаруживаем, что есть еще один CoordinatorLayout это обертывает наш макет координатора. Родитель CoordinatorLayout есть FrameLayout С BottomSheetBehaviorкод design_bottom_sheet. Высота peek, установленная из нашего кода выше, была ограничена из-за match_parent высота FrameLayout код design_bottom_sheet

путем установки высоты взглядаFrameLayout с идентификатором design_bottom_sheet эта проблема была решена

    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
        @Override
        public void onShow(DialogInterface dialog) {
            BottomSheetDialog d = (BottomSheetDialog) dialog;
            coordinatorLayout = (CoordinatorLayout) d.findViewById(R.id.locUXCoordinatorLayout);
            bottomSheetInternal = d.findViewById(R.id.locUXView);
            bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetInternal);
            bottomSheetBehavior.setHidable(false);
            BottomSheetBehavior.from((View)coordinatorLayout.getParent()).setPeekHeight(bottomSheetInternal.getHeight());
            bottomSheetBehavior.setPeekHeight(bottomSheetInternal.getHeight());
            coordinatorLayout.getParent().requestLayout();

        }
    });