让空视图在 RecyclerView 之后占用剩余 space?
Make empty view take up remaining space after RecyclerView?
我试图让一个空的彩色视图占据 RecyclerView 之后剩余的 space。我看过不同的 Whosebug 解决方案,但没有任何效果。基本上我想要这样的东西:
________________________
| |
| |
| |
| Recycler view |
| |
| ------------------- |
| colored empty view |
| |
| |
| |
| |
| |
_________________________
It should shrink as the RecyclerView grows.
________________________
| |
| |
| |
| Recycler view |
| |
| |
| |
| |
| |
| ------------------- |
| colored empty view |
| |
| |
_________________________
但是,如果 RecyclerView 超过一个屏幕的价值,则不应有空视图。这是我目前所拥有的:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/bla_bla_layout">
<android.support.v7.widget.RecyclerView
android:id="@+id/bla_bla_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View
android:background="@color/grayBackground"
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.melnykov.fab.FloatingActionButton
android:id="@+id/fab"
android:contentDescription="@string/add_bla"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
android:src="@drawable/add_bla_icon"
fab:fab_colorNormal="@color/primary"
fab:fab_colorPressed="@color/primary_pressed"
fab:fab_colorRipple="@color/ripple" />
</FrameLayout>
编辑
这不是上述问题的重复,如果您阅读这两个问题,您就会看到这一点。我的问题的解决方案应该纯粹是 xml,基于布局。 "empty view" 我的意思是现有 RecyclerView 下方的一些彩色矩形,而不是当 RecylerView 中没有数据时实际显示 "Empty view" 的文本视图。
试试这个
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bla_bla_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v7.widget.RecyclerView
android:id="@+id/bla_bla_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/array_sample" />
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/grayBackground" />
</LinearLayout>
看起来您可以使用一些对齐命令来完成 RelativeLayout
。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"/>
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/recycler_view"
android:layout_alignParentBottom="true"
android:background="@color/blue"/>
</RelativeLayout>
</FrameLayout>
我加入了 FrameLayout
因为你在另一条评论中提到你需要它与 FAB 一起使用。
如果将其加载到 AndroidStudio 中并开始为 RecyclerView
的高度设置样本宽度(50dp、150dp、300dp...),您将看到其下方的 View
开始调整它的高度也是如此。
Recycler 视图在运行时计算其高度,我们使用 LinearLayoutManager 指定其高度和宽度。
但问题是,现在 LinearLayoutManager 不支持 wrap_content 它始终使用 match_parent 作为它的高度。
所以你必须使用这个 LinearLayoutManager 而不是 android.support.v7.widget.LinearLayoutManager.
复制以上 java class 到你的包中并像下面那样使用它,
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this,
LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
// if it has fixed size
recyclerView.setHasFixedSize(true);
我对它进行了测试,它可以正常工作。
如果您只想在剩余的 space 中使用不同的颜色,请将 FrameLayout
的背景设置为所需的颜色并设置 RecyclerView
项目的 layout
背景变白。
这将导致剩余的 space 具有单独的颜色,并且 recyclerView
中填充项目的长度将根据您的需要变为白色。
如果您想在剩余的 space 中使用其他视图,例如 textView 或 ImageView,我想您将不得不扩展 RecyclerView class
和 override
计算高度的方法。
使用自定义 LinearLayoutManager 希望它能解决您的问题。
在您的 activity
中使用此代码
RecycleView rv= (RecyclerView) rootView.findViewById(R.id.recycler_view);
CustomLinearLayoutManager lm= new CustomLinearLayoutManager(mActivity);
lm.setOrientation(LinearLayoutManager.VERTICAL);
lm.setHasFixedSize(true);
rv.setLayoutManager(lm);
这是我的 CustomLinearLayoutManager
public class CustomLinearLayoutManager extends LinearLayoutManager {
public CustomLinearLayoutManager(Context context) {
super(context);
}
private int[] mMeasuredDimension = new int[2];
@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
int widthSpec, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);
measureScrapChild(recycler, 0,
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);
int width = mMeasuredDimension[0];
int height = mMeasuredDimension[1];
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
case View.MeasureSpec.AT_MOST:
width = widthSize;
break;
case View.MeasureSpec.UNSPECIFIED:
}
switch (heightMode) {
case View.MeasureSpec.EXACTLY:
case View.MeasureSpec.AT_MOST:
height = heightSize;
break;
case View.MeasureSpec.UNSPECIFIED:
}
setMeasuredDimension(width, height);
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
try {
View view = recycler.getViewForPosition(position);
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight(), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);
view.measure(childWidthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth();
measuredDimension[1] = view.getMeasuredHeight();
recycler.recycleView(view);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
我试图让一个空的彩色视图占据 RecyclerView 之后剩余的 space。我看过不同的 Whosebug 解决方案,但没有任何效果。基本上我想要这样的东西:
________________________
| |
| |
| |
| Recycler view |
| |
| ------------------- |
| colored empty view |
| |
| |
| |
| |
| |
_________________________
It should shrink as the RecyclerView grows.
________________________
| |
| |
| |
| Recycler view |
| |
| |
| |
| |
| |
| ------------------- |
| colored empty view |
| |
| |
_________________________
但是,如果 RecyclerView 超过一个屏幕的价值,则不应有空视图。这是我目前所拥有的:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/bla_bla_layout">
<android.support.v7.widget.RecyclerView
android:id="@+id/bla_bla_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View
android:background="@color/grayBackground"
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.melnykov.fab.FloatingActionButton
android:id="@+id/fab"
android:contentDescription="@string/add_bla"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
android:src="@drawable/add_bla_icon"
fab:fab_colorNormal="@color/primary"
fab:fab_colorPressed="@color/primary_pressed"
fab:fab_colorRipple="@color/ripple" />
</FrameLayout>
编辑 这不是上述问题的重复,如果您阅读这两个问题,您就会看到这一点。我的问题的解决方案应该纯粹是 xml,基于布局。 "empty view" 我的意思是现有 RecyclerView 下方的一些彩色矩形,而不是当 RecylerView 中没有数据时实际显示 "Empty view" 的文本视图。
试试这个
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bla_bla_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v7.widget.RecyclerView
android:id="@+id/bla_bla_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/array_sample" />
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@color/grayBackground" />
</LinearLayout>
看起来您可以使用一些对齐命令来完成 RelativeLayout
。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"/>
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/recycler_view"
android:layout_alignParentBottom="true"
android:background="@color/blue"/>
</RelativeLayout>
</FrameLayout>
我加入了 FrameLayout
因为你在另一条评论中提到你需要它与 FAB 一起使用。
如果将其加载到 AndroidStudio 中并开始为 RecyclerView
的高度设置样本宽度(50dp、150dp、300dp...),您将看到其下方的 View
开始调整它的高度也是如此。
Recycler 视图在运行时计算其高度,我们使用 LinearLayoutManager 指定其高度和宽度。
但问题是,现在 LinearLayoutManager 不支持 wrap_content 它始终使用 match_parent 作为它的高度。
所以你必须使用这个 LinearLayoutManager 而不是 android.support.v7.widget.LinearLayoutManager.
复制以上 java class 到你的包中并像下面那样使用它,
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this,
LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
// if it has fixed size
recyclerView.setHasFixedSize(true);
我对它进行了测试,它可以正常工作。
如果您只想在剩余的 space 中使用不同的颜色,请将 FrameLayout
的背景设置为所需的颜色并设置 RecyclerView
项目的 layout
背景变白。
这将导致剩余的 space 具有单独的颜色,并且 recyclerView
中填充项目的长度将根据您的需要变为白色。
如果您想在剩余的 space 中使用其他视图,例如 textView 或 ImageView,我想您将不得不扩展 RecyclerView class
和 override
计算高度的方法。
使用自定义 LinearLayoutManager 希望它能解决您的问题。
在您的 activity
中使用此代码 RecycleView rv= (RecyclerView) rootView.findViewById(R.id.recycler_view);
CustomLinearLayoutManager lm= new CustomLinearLayoutManager(mActivity);
lm.setOrientation(LinearLayoutManager.VERTICAL);
lm.setHasFixedSize(true);
rv.setLayoutManager(lm);
这是我的 CustomLinearLayoutManager
public class CustomLinearLayoutManager extends LinearLayoutManager {
public CustomLinearLayoutManager(Context context) {
super(context);
}
private int[] mMeasuredDimension = new int[2];
@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
int widthSpec, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);
measureScrapChild(recycler, 0,
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);
int width = mMeasuredDimension[0];
int height = mMeasuredDimension[1];
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
case View.MeasureSpec.AT_MOST:
width = widthSize;
break;
case View.MeasureSpec.UNSPECIFIED:
}
switch (heightMode) {
case View.MeasureSpec.EXACTLY:
case View.MeasureSpec.AT_MOST:
height = heightSize;
break;
case View.MeasureSpec.UNSPECIFIED:
}
setMeasuredDimension(width, height);
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
try {
View view = recycler.getViewForPosition(position);
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight(), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);
view.measure(childWidthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth();
measuredDimension[1] = view.getMeasuredHeight();
recycler.recycleView(view);
}
}catch(Exception e){
e.printStackTrace();
}
}
}