在 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
)表示会在其他layout
s which it下目前是!
因此,如果您想查看它是否工作正常,请设置 100dp
-50dp
(或您想要的特定大小可以看到 BottomSheetDialog
何时出现)而不是 wrap_content
到 NestedScrollView
那么您可能会看到下面的 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")
我在我的项目中使用了 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
)表示会在其他layout
s which it下目前是!
因此,如果您想查看它是否工作正常,请设置 100dp
-50dp
(或您想要的特定大小可以看到 BottomSheetDialog
何时出现)而不是 wrap_content
到 NestedScrollView
那么您可能会看到下面的 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")