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

12

我在我的项目中使用了BottomSheetDialogFragment,并按照以下方式设计:

BottomSheetDialogFragment

目标: 我想将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>

但是对话如下:

BottomSheetDialog

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

有人能帮我解决这个问题吗?


gravity设置为bottom怎么样?你还没有尝试过吗?另外,我看到你在一个RelativeLayout下面有几个视图,这可能是一个LinearLayout-FrameLayout,你可以在布局的顶部管理其他下面的布局。你可能想看一下:https://dev59.com/FHE95IYBdhLWcg3wQ7uc#4099076 - ʍѳђઽ૯ท
@ʍѳђઽ૯ท 我已经做到了,但实际上问题是,我将在BottomSheetDialog中执行此操作! 如果您查看这张图片,您会发现原因是什么: https://www.photobox.co.uk/my/photo?album_id=5392871352&photo_id=500985077017 - roghayeh hosseini
2个回答

8

在尝试过程中,我想到了几个解决方法,但均未能成功。

最终我通过以下方式解决了问题:

对于折叠模式,我将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- iconsContainer对齐方式(android:layout_alignParentBottom="true") enter image description here

这更像是一个自定义的BottomSheetDialogFragment,而不是我在答案中提到的BottomSheetDialog的问题。 - ʍѳђઽ૯ท

1
正如你所看到的,底部菜单一开始是不可见的。 有人可以帮我解决这个问题吗? 我猜测这种行为是完美的,因为你将NestedScrollView的layout_height设置为wrap_content,这意味着它将被内容包裹。 同时;
android:layout_alignParentBottom="true"

对于HorizontalScrollView(在layout下面)的意思是它将位于其他layouts之下,它目前就在那里!

因此,如果您要查看它是否正常工作,请将NestedScrollViewwrap_content设置为100dp-50dp(或者是可以在BottomSheetDialog弹出时看到的特定大小),然后您可能会看到下面的layout与其他layouts一起可见。

无论如何,这个布局中的所有东西看起来都是正确和良好的。图片也说了实话。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接