在 BottomSheetDialog 片段中将视图固定到屏幕底部

Pin a view to bottom of screen in BottomSheetDialog Fragment

我在我的项目中使用了 BottomSheetDialogFragment,我设计如下:

Target: 我要将 BottomSheetDialog 的底部菜单粘贴到屏幕底部,无论是折叠还是展开模式.

所以在 BottomSheetDialog 布局中,我使用 RelativeLayout 作为父级,"layout_alignParentBottom" 作为菜单容器,如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/bottomSheetContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
tools:context=".MyBottomSheetDialogFragment">

<RelativeLayout
    android:id="@+id/topSection"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true">
    ....
</RelativeLayout>

<android.support.v4.widget.NestedScrollView
    android:id="@+id/descriptionContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/topSection">
    ....
</android.support.v4.widget.NestedScrollView>

<HorizontalScrollView
    android:id="@+id/iconsContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true">
    ....
</HorizontalScrollView>
</RelativeLayout>

但对话如下:

如您所见,底部菜单一开始是不可见的。

谁能帮我解决这个问题?

As you can see, the bottom menu is not visible at first.

Can someone help me to solve this problem?

我猜这个行为 工作得很好 因为你设置了 layout_height of NestedScrollView (居中内容)wrap_content 也就是说,它会被 里面的内容包裹 .

同时;

android:layout_alignParentBottom="true"

To HorizontalScrollView (below layout)表示会在其他layouts which it下目前是!

因此,如果您想查看它是否工作正常,请设置 100dp-50dp(或您想要的特定大小可以看到 BottomSheetDialog 何时出现)而不是 wrap_contentNestedScrollView 那么您可能会看到下面的 layout 和其他 layout 将是可见的。

无论如何,此布局中的所有内容看起来都正确无误。还有图片说的是真的。

为了解决这个问题,我在尝试时想到了几件事,但都没有成功。

但是我终于通过这种方式解决了这个问题:

对于折叠模式,我将 bottomSheetBehavior 的 peekHeight 设置为屏幕的 1/3(使用以下代码):

    View bottomSheetContainer = dialog.findViewById(R.id.bottomSheetContainer);
    View parent = (View) bottomSheetContainer.getParent();
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) parent.getLayoutParams();
    BottomSheetBehavior bottomSheetBehavior = (BottomSheetBehavior) params.getBehavior();
    View inflatedView = View.inflate(getContext(), R.layout.word_details_bottom_sheet, null);
    inflatedView.measure(0, 0);
    int screenHeight = getActivity().getResources().getDisplayMetrics().heightPixels;

    if (bottomSheetBehavior != null) {
        bottomSheetBehavior.setPeekHeight(screenHeight /3);
    }

所以我决定去做:

1- 对于折叠模式:bottomSheet 容器的高度 = bottomSheetBehavior 的 peekHeight

2-展开模式:bottomSheet容器的高度=全屏高度

所以我写了下面的代码(完整代码):

WordDetailsBottomSheet.java

public class WordDetailsBottomSheet extends BottomSheetDialogFragment {

public WordDetailsBottomSheet() { // Required empty public constructor }

@NotNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    BottomSheetDialog dialog = new BottomSheetDialog(getActivity(), 0);
    dialog.setContentView(R.layout.word_details_bottom_sheet);

    View bottomSheetContainer = dialog.findViewById(R.id.bottomSheetContainer);
    View parent = (View) bottomSheetContainer.getParent();
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) parent.getLayoutParams();
    BottomSheetBehavior bottomSheetBehavior = (BottomSheetBehavior) params.getBehavior();
    View inflatedView = View.inflate(getContext(), R.layout.word_details_bottom_sheet, null);
    inflatedView.measure(0, 0);
    int screenHeight = getActivity().getResources().getDisplayMetrics().heightPixels;
    int statusBarHeight = getStatusBarHeight();

    if (bottomSheetBehavior != null) {
        bottomSheetBehavior.setPeekHeight(screenHeight / BOTTOM_SHEET_PEEK_HEIGHT_PERCENT);
        bottomSheetContainer.getLayoutParams().height = bottomSheetBehavior.getPeekHeight();
    }

    bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View view, int newState) {
            switch (newState) {
                case BottomSheetBehavior.STATE_EXPANDED:
                    bottomSheetContainer.getLayoutParams().height = screenHeight-statusBarHeight;
                    break;
                case BottomSheetBehavior.STATE_COLLAPSED:
                    bottomSheetContainer.getLayoutParams().height = bottomSheetBehavior.getPeekHeight();
                    break;
                case BottomSheetBehavior.STATE_HIDDEN:
                    dismiss();
                    break;
                default:
                    break;
            }
        }

        @Override
        public void onSlide(@NonNull View view, float slideOffset) {
        }
    });

    return dialog;
}

public int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
    }
}

word_details_bottom_sheet.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/bottomSheetContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
tools:context=".MyBottomSheetDialogFragment">

<RelativeLayout
android:id="@+id/topSection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
....
</RelativeLayout>

<android.support.v4.widget.NestedScrollView
android:id="@+id/descriptionContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/topSection">
....
</android.support.v4.widget.NestedScrollView>

<HorizontalScrollView
android:id="@+id/iconsContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
....
</HorizontalScrollView>
</RelativeLayout>

在 xml 文件中,重要的是:

1- 父 ID (android:id="@+id/bottomSheetContainer")

2- 图标容器对齐 (android:layout_alignParentBottom="true")