Android 如何保持碎片高度始终与父级匹配?
我在一个项目中实现了一个Android 如何保持碎片高度始终与父级匹配?,android,android-recyclerview,bottom-sheet,Android,Android Recyclerview,Bottom Sheet,我在一个项目中实现了一个BottomSheetDialogFragment,这让我遇到了麻烦。 我有一个底页,其中包含一个搜索视图和一个回收视图。对话框片段显示正确,内容丰富,都很好。 当我使用SearchView过滤Recyclerview的结果时,问题就开始了,因为当有5个或更少的结果时,键盘与现在很小的Recyclerview重叠 我想知道是否有可能将底页的高度保持为match\u parent或填充窗口的东西,或者保持Recyclerview足够大,以避免键盘“弄乱”结果。我使用以下方法
BottomSheetDialogFragment
,这让我遇到了麻烦。我有一个
底页
,其中包含一个搜索视图
和一个回收视图
。对话框片段显示正确,内容丰富,都很好。当我使用
SearchView
过滤Recyclerview
的结果时,问题就开始了,因为当有5个或更少的结果时,键盘与现在很小的Recyclerview
重叠我想知道是否有可能将
底页的高度保持为match\u parent
或填充窗口的东西,或者保持Recyclerview
足够大,以避免键盘“弄乱”结果。我使用以下方法使片段在打开时展开:
private fun expandBottomSheet() {
view?.viewTreeObserver?.addOnGlobalLayoutListener {
val dialog = dialog as BottomSheetDialog
val bottomSheet = dialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
val behavior = BottomSheetBehavior.from<View>(bottomSheet)
behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
}
private-fun-expandBottomSheet(){
查看?.viewTreeObserver?.addOnGlobalLayoutListener{
val dialog=对话框作为底部对话框
val bottomSheet=dialog.findviewbyd(com.google.android.material.R.id.design\u bottom\u sheet)
val behavior=BottomSheetBehavior.from(bottomSheet)
behavior.state=BottomSheetBehavior.state\u已展开
}
}
我的工作表XML如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="@string/bottom_sheet_behavior">
<View
android:layout_width="52dp"
android:layout_height="7dp"
android:layout_gravity="center"
android:layout_marginTop="@dimen/size_small_4"
android:layout_marginBottom="@dimen/size_small_4"
android:background="@drawable/border_top_swipe_indicator" />
<androidx.appcompat.widget.SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:iconifiedByDefault="false"
app:queryHint="@string/text_type_your_query" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/border_top_white"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/list_item" />
</LinearLayout>
提前感谢您的帮助
编辑:
包含Recyclerview
和stuff的底页是一个子片段(从另一个片段实例化的片段)。在manifest.xml文件中,为应用程序声明了活动。在
那应该对你有用。这可能会导致糟糕的UI和UX,具体取决于您的视图。如果这是真的,您可以在搜索视图上设置焦点侦听器,当它获得焦点时,以编程方式将底部工作表的状态设置为“展开”。看看答案 在manifest.xml文件中,为应用程序声明了活动。在
那应该对你有用。这可能会导致糟糕的UI和UX,具体取决于您的视图。如果这是真的,您可以在搜索视图上设置焦点侦听器,当它获得焦点时,以编程方式将底部工作表的状态设置为“展开”。看看答案 尽管我对我提出的修复方案不满意,但我不得不说它运行得很顺利。
基本上,我用一个ViewPager
包装了我的底页,它没有调整大小。
我承认这是一个黑客,我希望有人能提供一个更体面的答案。同时,ViewPager
带有一张底页的ViewPager
是一个不错的选择。尽管我对我提出的解决方案不满意,但我不得不说它工作得很顺利。
基本上,我用一个ViewPager
包装了我的底页,它没有调整大小。
我承认这是一个黑客,我希望有人能提供一个更体面的答案。同时,ViewPager
带有一张底页的方法是。您可以在创建活动时使用下面的代码设置高度
view?.viewTreeObserver?.addOnGlobalLayoutListener {
val rect = Rect()
view?.getWindowVisibleDisplayFrame(rect)
val screenHeight = view?.rootView?.height
val keyPadHeight = screenHeight?.minus(rect.bottom)
if (screenHeight != null) {
if (keyPadHeight != 0) {
if (view?.paddingBottom != keyPadHeight) {
view?.setPadding(0, 0, 0, keyPadHeight!!)
}
} else {
if (view?.paddingBottom != 0) {
view?.setPadding(0, 0, 0, 0)
}
}
希望这对您有用。您可以在“创建活动”中使用以下代码设置高度
view?.viewTreeObserver?.addOnGlobalLayoutListener {
val rect = Rect()
view?.getWindowVisibleDisplayFrame(rect)
val screenHeight = view?.rootView?.height
val keyPadHeight = screenHeight?.minus(rect.bottom)
if (screenHeight != null) {
if (keyPadHeight != 0) {
if (view?.paddingBottom != keyPadHeight) {
view?.setPadding(0, 0, 0, keyPadHeight!!)
}
} else {
if (view?.paddingBottom != 0) {
view?.setPadding(0, 0, 0, 0)
}
}
希望这对您有用。对于正在搜索此问题的任何人,如果您想强制您的BottomSheetDialogFragment
具有全屏高度,只需将底部工作表内容布局包装在此自定义框架布局内:
public class MatchParentFrameLayout extends FrameLayout {
public MatchParentFrameLayout(@NonNull Context context) {
super(context);
}
public MatchParentFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MatchParentFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MatchParentFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
对于正在搜索此问题的任何人,如果要强制您的BottomSheetDialogFragment
具有全屏高度,只需将您的底部工作表内容布局包装在此自定义框架布局内:
public class MatchParentFrameLayout extends FrameLayout {
public MatchParentFrameLayout(@NonNull Context context) {
super(context);
}
public MatchParentFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MatchParentFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MatchParentFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}