如何使用BottomSheetDialog?

Igo*_*lov 28 android android-support-library

我想尝试Android支持库23.2中引入的BottomSheetDialog,但它似乎无法正常工作.以下是该文档所说的内容:

当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));
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的布局文件:

<?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>
Run Code Online (Sandbox Code Playgroud)

然后我在我的Activity中使用以下代码:

new AccountActionsDialog(this).show();
Run Code Online (Sandbox Code Playgroud)

我的屏幕变暗,但我的对话框内容不可见.有什么可能遗漏的想法?当我使用AppCompatDialog时,它工作正常.

Gun*_*lan 6

您可以简单地在 Activity/Fragment 中为 BottomSheetDialog 创建一个实例,而不是使用单独的类,如下所示,您可以使用它。我认为这非常容易和简单。

val dialog = BottomSheetDialog(this)
val bottomSheet = layoutInflater.inflate(R.layout.bottom_sheet, null)

bottomSheet.buttonSubmit.setOnClickListener { dialog.dismiss() }
        
dialog.setContentView(bottomSheet)
dialog.show()
Run Code Online (Sandbox Code Playgroud)


小智 4

这是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>
Run Code Online (Sandbox Code Playgroud)

您的内容视图位于视图内部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);
}
Run Code Online (Sandbox Code Playgroud)

它的本意是定位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);
Run Code Online (Sandbox Code Playgroud)

插入的

mMaxOffset = mParentHeight - child.getHeight();
Run Code Online (Sandbox Code Playgroud)