Подтвердить что ты не робот

BottomSheetDialogFragment - Как установить расширенную высоту (или минимальное смещение)

Я создаю 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 оставляет место сверху...

4b9b3361

Ответ 1

Высота оборачивается из-за того, что раздутый вид добавляется в FrameLayout, который имеет layout_height=wrap_content. См. FrameLayout (R.id.design_bottom_sheet) на https://github.com/dandar3/android-support-design/blob/master/res/layout/design_bottom_sheet_dialog.xml.

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

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)

        });
    }

}

--- ОБНОВЛЕНИЕ 30 августа 2018 г. --- Год спустя я понял, что фон был окрашен при неправильном просмотре. это перетаскивало фон вместе с содержимым, пока пользователь перетаскивал диалог. Я исправил это так, чтобы родительский вид нижнего листа был цветным.

Ответ 2

Я нашел гораздо более простой ответ; в вашем примере, где вы получаете FrameLayout для нижнего листа, используя этот код

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

вы можете установить высоту в параметрах макета для этого представления для любой высоты, на которую вы хотите установить расширенную высоту.

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

Ответ 3

БОЛЬШОЕ ОБНОВЛЕНИЕ Чтобы избежать дублирования кода, я даю ссылку на полный ответ, где вы можете найти все объяснения о том, как получить полное поведение, например, Карты Google.


Я хочу настроить максимальную расширенную высоту. Как я могу это сделать?

Оба BottomSheet и BottomSheetDialogFragment используют BottomSheetBehavior, который вы можете найти в библиотеке поддержки 23.x

Этот класс Java имеет 2 различных использования для mMinOffset, один из них используется для определения области родителя, которую он будет использовать для рисования своего контента (возможно, NestedScrollView). И другой вариант, если для определения расширенной точки привязки, я имею в виду, если вы сдвинете ее вверх по форме STATE_COLLAPSED, она будет анимировать ваш BottomSheet, пока он не достигнет этой точки привязки, НО, если вы все еще можете продолжать скользить вверх, чтобы покрыть всю родительскую высоту (Высота 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. Измените следующие методы: onLayoutChild, onStopNestedScroll, BottomSheetBehavior<V> from(V view) и setState (необязательно)

А вот как это выглядит:
[CustomBottomSheetBehavior]

Ответ 4

Котлин

В моем случае мне нужно определить фиксированную высоту, и я сделал следующее:

val bottomSheet: View? = dialog.findViewById(R.id.design_bottom_sheet)
BottomSheetBehavior.from(bottomSheet!!).peekHeight = 250

таким образом, у вас также есть доступ к любому свойству BottomSheetBehavior, например halfExpandedRatio