Android 如何在 RecyclerView 中的项目之间添加分隔线和空格?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24618829/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add dividers and spaces between items in RecyclerView?
提问by EyesClear
This is an example of how it could have been done previously in the ListView
class, using the dividerand dividerHeightparameters:
这是以前在ListView
类中如何使用divider和dividerHeight参数完成的示例:
<ListView
android:id="@+id/activity_home_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@android:color/transparent"
android:dividerHeight="8dp"/>
However, I don't see such possibility in the RecyclerView
class.
但是,我在RecyclerView
课堂上看不到这种可能性。
<android.support.v7.widget.RecyclerView
android:id="@+id/activity_home_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
In that case, is it ok to define margins and/or add a custom divider view directly into a list item's layout or is there a better way to achieve my goal?
在这种情况下,是否可以定义边距和/或将自定义分隔线视图直接添加到列表项的布局中,或者是否有更好的方法来实现我的目标?
回答by EyesClear
October 2016 Update
2016 年 10 月更新
The version 25.0.0 of Android Support Library introduced DividerItemDecoration
class:
Android Support Library 25.0.0 版本引入了DividerItemDecoration
类:
DividerItemDecoration is a RecyclerView.ItemDecoration that can be used as a divider between items of a
LinearLayoutManager
. It supports bothHORIZONTAL
andVERTICAL
orientations.
DividerItemDecoration 是一个 RecyclerView.ItemDecoration,可用作
LinearLayoutManager
. 它支持HORIZONTAL
和VERTICAL
方向。
Usage:
用法:
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
layoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);
Previous answer
上一个答案
Some answers either use methods that have since become deprecated, or don't give a complete solution, so I tried to do a short, up-to-date wrap-up.
一些答案要么使用已被弃用的方法,要么没有给出完整的解决方案,所以我尝试做一个简短的、最新的总结。
Unlike ListView
, the RecyclerView
class has no divider-related parameters. Instead, you need to extend ItemDecoration
, a RecyclerView
's inner class:
与 不同ListView
,RecyclerView
该类没有与分隔符相关的参数。相反,您需要扩展ItemDecoration
aRecyclerView
的内部类:
An
ItemDecoration
allows the application to add a special drawing and layout offset to specific item views from the adapter's data set. This can be useful for drawing dividers between items, highlights, visual grouping boundaries and more.All
ItemDecorations
are drawn in the order they were added, before the item views (inonDraw()
) and after the items (in onDrawOver(Canvas
,RecyclerView
,RecyclerView.State)
.
An
ItemDecoration
允许应用程序向适配器数据集中的特定项目视图添加特殊的绘图和布局偏移。这对于在项目、突出显示、视觉分组边界等之间绘制分隔线非常有用。所有
ItemDecorations
都按照它们添加的顺序绘制,在项目视图之前(在onDraw()
)和在项目之后(在 onDrawOver(Canvas
,RecyclerView
,RecyclerView.State)
.
Vertical
spacing ItemDecoration
Vertical
间距 ItemDecoration
Extend ItemDecoration
, add custom constructor which takes space height
as a parameter and override getItemOffsets()
method:
Extend ItemDecoration
,添加以空间height
为参数和覆盖getItemOffsets()
方法的自定义构造函数:
public class VerticalSpaceItemDecoration extends RecyclerView.ItemDecoration {
private final int verticalSpaceHeight;
public VerticalSpaceItemDecoration(int verticalSpaceHeight) {
this.verticalSpaceHeight = verticalSpaceHeight;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
outRect.bottom = verticalSpaceHeight;
}
}
If you don't want to insert space below the last item, add the following condition:
如果不想在最后一项下方插入空格,请添加以下条件:
if (parent.getChildAdapterPosition(view) != parent.getAdapter().getItemCount() - 1) {
outRect.bottom = verticalSpaceHeight;
}
Note: you can also modify outRect.top
, outRect.left
and outRect.right
properties for desired effect.
注意:您还可以修改outRect.top
,outRect.left
和outRect.right
属性以获得所需的效果。
Divider ItemDecoration
分隔线 ItemDecoration
Extend ItemDecoration
and override onDraw()
method:
扩展ItemDecoration
和覆盖onDraw()
方法:
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private Drawable divider;
/**
* Default divider will be used
*/
public DividerItemDecoration(Context context) {
final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
divider = styledAttributes.getDrawable(0);
styledAttributes.recycle();
}
/**
* Custom divider will be used
*/
public DividerItemDecoration(Context context, int resId) {
divider = ContextCompat.getDrawable(context, resId);
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + divider.getIntrinsicHeight();
divider.setBounds(left, top, right, bottom);
divider.draw(c);
}
}
}
You can either call the first constructor that uses the default Android divider attributes, or the second one that uses your own drawable, for example drawable/divider.xml
您可以调用使用默认 Android 分隔符属性的第一个构造函数,或者调用使用您自己的可绘制对象的第二个构造函数,例如 drawable/divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="1dp" />
<solid android:color="#ff992900" />
</shape>
Note: if you want the divider to be drawn overyour items, override onDrawOver()
method instead.
注意:如果您希望在您的项目上绘制分隔线,请onDrawOver()
改用覆盖方法。
Usage
用法
To use your new class add VerticalSpaceItemDecoration
or DividerSpaceItemDecoration
to RecyclerView
, for example in your fragment's onCreateView()
method:
要使用您的新类 addVerticalSpaceItemDecoration
或DividerSpaceItemDecoration
to RecyclerView
,例如在您的片段onCreateView()
方法中:
private static final int VERTICAL_ITEM_SPACE = 48;
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_feed, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_home_recycler_view);
linearLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(linearLayoutManager);
//add ItemDecoration
recyclerView.addItemDecoration(new VerticalSpaceItemDecoration(VERTICAL_ITEM_SPACE));
//or
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));
//or
recyclerView.addItemDecoration(
new DividerItemDecoration(getActivity(), R.drawable.divider));
recyclerView.setAdapter(...);
return rootView;
}
There's also Lucas Rocha's librarywhich is supposed to simplify the item decoration process. Haven't tried it though.
还有Lucas Rocha 的图书馆,旨在简化物品装饰过程。不过没试过。
Among its featuresare:
它的特点包括:
- A collection of stock item decorations including:
- Item spacing Horizontal/vertical dividers.
- List item
- 库存装饰品的集合,包括:
- 项目间距水平/垂直分隔线。
- 项目清单
回答by Leo Droidcoder
Just add
只需添加
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
DividerItemDecoration.VERTICAL));
Also you may need to add the dependencycompile 'com.android.support:recyclerview-v7:27.1.0'
您也可能需要添加依赖项compile 'com.android.support:recyclerview-v7:27.1.0'
EDIT:
编辑:
For customizing it a little bit you can add a custom drawable:
为了稍微自定义它,您可以添加一个自定义 drawable:
DividerItemDecoration itemDecorator = new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL);
itemDecorator.setDrawable(ContextCompat.getDrawable(getContext(), R.drawable.divider));
You are free to use any custom drawable, for instance:
您可以自由使用任何自定义 drawable,例如:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/colorPrimary"/>
<size android:height="0.5dp"/>
</shape>
回答by Duy Nguyen
Might I direct your attention to this particular file on Github by Alex Fu: https://gist.github.com/alexfu/0f464fc3742f134ccd1e
我可以让您注意 Alex Fu 在 Github 上的这个特定文件:https: //gist.github.com/alexfu/0f464fc3742f134ccd1e
It's the DividerItemDecoration.java example file "pulled straight from the support demos".(https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS)
这是 DividerItemDecoration.java 示例文件“直接从支持演示中提取”。(https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS)
I was able to get divider lines nicely after importing this file in my project and add it as an item decoration to the recycler view.
在我的项目中导入此文件并将其作为项目装饰添加到回收器视图后,我能够很好地获得分隔线。
Here's how my onCreateView look like in my fragment containing the Recyclerview:
这是我的 onCreateView 在包含 Recyclerview 的片段中的样子:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_recycler_view, container, false);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view);
mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
return rootView;
}
I'm sure additional styling can be done, but it's a starting point. :)
我确信可以完成其他样式,但这是一个起点。:)
回答by SergeyA
Simple ItemDecoration
implementation for equal spaces between all items.
ItemDecoration
所有项目之间等距的简单实现。
public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
private int space;
public SpacesItemDecoration(int space) {
this.space = space;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.left = space;
outRect.right = space;
outRect.bottom = space;
// Add top margin only for the first item to avoid double space between items
if(parent.getChildAdapterPosition(view) == 0) {
outRect.top = space;
}
}
}
回答by Madan Sapkota
The simple one is to set background color for RecyclerViewand different background color for items. Here is an example ...
简单的一种是为RecyclerView设置背景颜色,为项目设置不同的背景颜色。这是一个例子......
<android.support.v7.widget.RecyclerView
android:background="#ECEFF1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"/>
and the TextViewitem (It can be anything though) with bottom margin "x" dp or px.
以及底部边距为“x”dp 或 px的TextView项目(它可以是任何东西)。
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="1dp"
android:background="#FFFFFF"/>
The output ...
输出 ...
回答by Belal mazlom
I think using simple divider will help you
To add divider to each item:
1- Add this to drawable directory line_divider.xml
我认为使用简单的分隔线将帮助您
为每个项目添加分隔线:
1- 将此添加到可绘制目录line_divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="1dp"
android:height="1dp" />
<solid android:color="#999999" />
</shape>
2- Create SimpleDividerItemDecoration class
I used this example to define this class:
https://gist.github.com/polbins/e37206fbc444207c0e92
2-创建 SimpleDividerItemDecoration 类
我用这个例子来定义这个类:https:
//gist.github.com/polbins/e37206fbc444207c0e92
package com.example.myapp;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.example.myapp.R;
public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration{
private Drawable mDivider;
public SimpleDividerItemDecoration(Resources resources) {
mDivider = resources.getDrawable(R.drawable.line_divider);
}
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
}
3- In activity or fragment that using RecyclerView, inside onCreateView add this:
3- 在使用 RecyclerView 的活动或片段中,在 onCreateView 中添加以下内容:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
RecyclerView myRecyclerView = (RecyclerView) layout.findViewById(R.id.my_recycler_view);
myRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(getResources()));
....
}
4- To add spacing between Items
you just need to add padding property to your item view
4- 要在项目之间添加间距,
您只需将填充属性添加到项目视图
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:padding="4dp"
>
..... item structure
</RelativeLayout>
回答by Javanator
As I have set ItemAnimators
. The ItemDecorator
don't enter or exit along with the animation.
正如我所设定的ItemAnimators
。在ItemDecorator
不进入或与动画退出。
I simply ended up in having a view line in my item view layout file of each item. It solved my case. DividerItemDecoration
felt to be too much of sorcery for a simple divider.
我只是在每个项目的项目视图布局文件中都有一个视图行。它解决了我的情况。DividerItemDecoration
感觉对于一个简单的分隔器来说太神奇了。
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="@color/lt_gray"/>
回答by Faheem
This is simple, you don't need such complicated code
这很简单,你不需要这么复杂的代码
DividerItemDecoration divider = new
DividerItemDecoration(mRVMovieReview.getContext(),
DividerItemDecoration.VERTICAL);
divider.setDrawable(
ContextCompat.getDrawable(getBaseContext(), R.drawable.line_divider)
);
mRVMovieReview.addItemDecoration(divider);
Add this in your drawable : line_divider.xml
将此添加到您的 drawable 中:line_divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="1dp" />
<solid android:color="@android:color/black" />
</shape>
回答by Yoann Hercouet
Since there is no right way to implement this yet properly using Material Design, I just did the following trick to add a divider on the list item directly:
由于还没有使用 Material Design 正确实现这一点的正确方法,我只是做了以下技巧直接在列表项上添加分隔符:
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/dividerColor"/>
回答by Gent Berani
The way how I'm handling the Divider view and also Divider Insets is by adding a RecyclerView extension.
我处理 Divider 视图和 Divider Insets 的方式是添加 RecyclerView 扩展。
1.
1.
Add a new extension file by naming View or RecyclerView:
通过命名 View 或 RecyclerView 添加一个新的扩展文件:
RecyclerViewExtension.kt
and add the setDivider
extension method inside the RecyclerViewExtension.kt file.
并setDivider
在 RecyclerViewExtension.kt 文件中添加扩展方法。
/*
* RecyclerViewExtension.kt
* */
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView
fun RecyclerView.setDivider(@DrawableRes drawableRes: Int) {
val divider = DividerItemDecoration(
this.context,
DividerItemDecoration.VERTICAL
)
val drawable = ContextCompat.getDrawable(
this.context,
drawableRes
)
drawable?.let {
divider.setDrawable(it)
addItemDecoration(divider)
}
}
2.
2.
Create a Drawable resource file inside of drawable
package like recycler_view_divider.xml
:
在drawable
包内创建一个 Drawable 资源文件,如recycler_view_divider.xml
:
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="10dp"
android:insetRight="10dp">
<shape>
<size android:height="0.5dp" />
<solid android:color="@android:color/darker_gray" />
</shape>
</inset>
where you can specify the left and right marginon android:insetLeft
and android:insetRight
.
在这里你可以指定左,右缘上android:insetLeft
和android:insetRight
。
3.
3.
On your Activity or Fragment where the RecyclerView is initialized, you can set the custom drawable by calling:
在初始化 RecyclerView 的 Activity 或 Fragment 上,您可以通过调用来设置自定义 drawable:
recyclerView.setDivider(R.drawable.recycler_view_divider)
4.
4.
Cheers
干杯