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

Как использовать BottomSheetDialog?

Я хочу попробовать BottomSheetDialog, представленный в Android Support Library 23.2, но он работает некорректно. Вот что говорит doc:

В то время как BottomSheetBehavior фиксирует стойкий нижний регистр, этот выпуск также предоставляет BottomSheetDialog и BottomSheetDialogFragment для заполнения модального нижнего листка. Просто замените AppCompatDialog или AppCompatDialogFragment на свой нижние листы, чтобы ваш диалог был создан как нижний лист ".

Итак, я изменил свой AppCompatDialog на BottomSheetDialog:

package my.package.ui.dialog;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.BottomSheetDialog;

import my.package.R;

public class AccountActionsDialog extends BottomSheetDialog {
    public AccountActionsDialog(Context context) {
        super(context);

        if (context instanceof Activity) {
            setOwnerActivity((Activity) context);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getLayoutInflater().inflate(R.layout.dialog_account_actions, null));
    }
}

Вот мой файл макета:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ff0000"
        android:padding="16dp"
        android:text="Delete account"
        android:textColor="#ffffff" />

</LinearLayout>

Затем я использую следующий код в своей работе:

new AccountActionsDialog(this).show();

Мой экран становится тусклым, но содержимое моего диалога не отображается. Любые мысли о том, что может отсутствовать? Он отлично работает, когда я использую AppCompatDialog.

4b9b3361

Ответ 1

Это файл макета BottomSheetDialog.

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:soundEffectsEnabled="false">

<FrameLayout
        android:id="@+id/design_bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        app:layout_behavior="@string/bottom_sheet_behavior"
        style="?attr/bottomSheetStyle"/>

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

Ваше представление содержимого находится внутри представления design_bottom_sheet, оно будет располагаться по центру вертикально на CoordinatorLayout, а BottomSheetBehavior будет его компенсировать.

mParentHeight = parent.getHeight();
mMinOffset = Math.max(0, mParentHeight - child.getHeight());
mMaxOffset = mParentHeight - mPeekHeight;
if (mState == STATE_EXPANDED) {
    ViewCompat.offsetTopAndBottom(child, mMinOffset);
} else if (mHideable && mState == STATE_HIDDEN) {
    ViewCompat.offsetTopAndBottom(child, mParentHeight);
} else if (mState == STATE_COLLAPSED) {
    ViewCompat.offsetTopAndBottom(child, mMaxOffset);
}

Он намеревался positon design_bottom_sheet в mMaxOffset, но на самом деле начальный getTop дочернего представления не равен 0, а (mParentHeight - childHeight) / 2, поэтому вы просматриваете, если смещение больше требуемого смещения.

Найдите представление design_bottom_sheet и установите его значение силы на Gravity.TOP | Gravity.CENTER_HORIZONTAL, чтобы исправить его. Но, если childHeight меньше, чем mPeekHeight, будет ниже области содержимого ниже вашего содержимого.

Однако, если peekHeight > childHeight, mMaxOffset будет меньше mMinOffset, что вызовет странное поведение.

Возможно, код должен быть изменен на

mMaxOffset = Math.max((mParentHeight - mPeekHeight), mMinOffset);

insted

mMaxOffset = mParentHeight - child.getHeight();

Ответ 2

Я выделял ту же проблему, тусклый фон и содержимое не было видно. Вот как мне удалось обойти это, установив представление содержимого в скрытом методе setupDialog().

public class CustomBottomSheetDialogFragment extends BottomSheetDialogFragment {

    private TextView mOffsetText;
    private TextView mStateText;
    private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {

        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            setStateText(newState);
            if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                dismiss();
            }

        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
            setOffsetText(slideOffset);
        }
    };
    private LinearLayoutManager mLinearLayoutManager;
    private ApplicationAdapter mAdapter;

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return super.onCreateDialog(savedInstanceState);
    }

    @Override
    public void onViewCreated(View contentView, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(contentView, savedInstanceState);
    }

    @Override
    public void setupDialog(Dialog dialog, int style) {
        super.setupDialog(dialog, style);
        View contentView = View.inflate(getContext(), R.layout.bottom_sheet_dialog_content_view, null);
        dialog.setContentView(contentView);
       mBottomSheetBehavior = BottomSheetBehavior.from(((View) contentView.getParent()));
        if (mBottomSheetBehavior != null) {
            mBottomSheetBehavior.setBottomSheetCallback(mBottomSheetBehaviorCallback);   
        }
        mOffsetText = (TextView) contentView.findViewById(R.id.offsetText);
        mStateText = (TextView) contentView.findViewById(R.id.stateText);
    }

}

И макет:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <TextView
        android:id="@+id/offsetText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/black" />

    <TextView
        android:id="@+id/stateText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/black" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Ответ 3

Здесь проблема на code.google.com https://code.google.com/p/android/issues/detail?id=201793

Проблема, которую некоторые пользователи видят, сводится к FrameLayout, которая ограничивает вертикальное отображение нашего контента. BottomSheetBehavior работает только в том случае, если это представление выровнено сверху. Я не понял, что заставляет FrameLayout центрироваться по вертикали еще, но здесь возможно обходное решение:

View contentView = ...
// You may have to measure your content view first.
dialog.setContentView(contentView);

// Change this to a percentage or a constant, whatever you want to do.
// The default is 1024 - any views smaller than this will be pulled off 
// the bottom of the screen.
float peekHeight = contentView.getMeasuredHeight();

View parent = (View)contentView.getParent();
BottomSheetBehavior behavior = BottomSheetBehavior.from(parent);
behavior.setPeekHeight(peekHeight);
CoordinatorLayout.LayoutParams layoutParams = 
   (CoordinatorLayout.LayoutParams)parent.getLayoutParams();
layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;

Ответ 4

Он начал работать, когда я установил фиксированную высоту для моего TextView (200dp), хотя для некоторых значений высоты он по-прежнему ведет себя некорректно. Очевидно, это проблема поддержки lib. В отладчике ошибок есть несколько сообщений, связанных с BottomSheetDialog:

https://code.google.com/p/android/issues/detail?id=201793&sort=-opened&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened

https://code.google.com/p/android/issues/detail?id=201826