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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:31:01  来源:igfitidea点击:

How to add dividers and spaces between items in RecyclerView?

androidandroid-recyclerviewdivider

提问by EyesClear

This is an example of how it could have been done previously in the ListViewclass, using the dividerand dividerHeightparameters:

这是以前在ListView类中如何使用dividerdividerHeight参数完成的示例:

<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 RecyclerViewclass.

但是,我在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 DividerItemDecorationclass:

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 both HORIZONTALand VERTICALorientations.

DividerItemDecoration 是一个 RecyclerView.ItemDecoration,可用作LinearLayoutManager. 它支持HORIZONTALVERTICAL方向。

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 RecyclerViewclass has no divider-related parameters. Instead, you need to extend ItemDecoration, a RecyclerView's inner class:

与 不同ListViewRecyclerView该类没有与分隔符相关的参数。相反,您需要扩展ItemDecorationaRecyclerView的内部类:

An ItemDecorationallows 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 ItemDecorationsare drawn in the order they were added, before the item views (in onDraw()) and after the items (in onDrawOver(Canvas, RecyclerView, RecyclerView.State).

AnItemDecoration允许应用程序向适配器数据集中的特定项目视图添加特殊的绘图和布局偏移。这对于在项目、突出显示、视觉分组边界等之间绘制分隔线非常有用。

所有ItemDecorations都按照它们添加的顺序绘制,在项目视图之前(在onDraw())和在项目之后(在 onDrawOver( Canvas, RecyclerView, RecyclerView.State).

Verticalspacing ItemDecoration

Vertical间距 ItemDecoration

Extend ItemDecoration, add custom constructor which takes space heightas 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.leftand outRect.rightproperties for desired effect.

注意:您还可以修改outRect.top,outRect.leftoutRect.right属性以获得所需的效果。

Divider ItemDecoration

分隔线 ItemDecoration

Extend ItemDecorationand 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 VerticalSpaceItemDecorationor DividerSpaceItemDecorationto RecyclerView, for example in your fragment's onCreateView()method:

要使用您的新类 addVerticalSpaceItemDecorationDividerSpaceItemDecorationto 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 dependency
compile '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 ItemDecorationimplementation 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 ...

输出 ...

enter image description here

在此处输入图片说明

回答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 ItemDecoratordon'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. DividerItemDecorationfelt 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 setDividerextension 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 drawablepackage 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:insetLeftand android:insetRight.

在这里你可以指定左,右android:insetLeftandroid: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

干杯

RecyclerView row with divider.

带分隔线的 RecyclerView 行。