如何在 RecyclerView 中的项目之间添加分隔线和空格 [英] How to add dividers and spaces between items in RecyclerView

查看:53
本文介绍了如何在 RecyclerView 中的项目之间添加分隔线和空格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This is an example of how it could have been done previously in the ListView class, using the divider and dividerHeight parameters:

<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"/>

但是,我在 RecyclerView 类中没有看到这种可能性.

However, I don't see such possibility in the RecyclerView class.

<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?

推荐答案

2016 年 10 月更新

Android Support Library 25.0.0 版引入了<代码>DividerItemDecoration 类:

The version 25.0.0 of Android Support Library introduced the DividerItemDecoration class:

DividerItemDecoration 是一个 RecyclerView.ItemDecoration,可用作 LinearLayoutManager 的项目之间的分隔线.它支持 HORIZONTALVERTICAL 方向.

DividerItemDecoration is a RecyclerView.ItemDecoration that can be used as a divider between items of a LinearLayoutManager. It supports both HORIZONTAL and VERTICAL orientations.

用法:

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
    layoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);


上一个回答

有些答案要么使用已被弃用的方法,要么没有给出完整的解决方案,所以我尝试做一个简短的最新总结.

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.

ListView 不同,RecyclerView 类没有任何与分隔符相关的参数.相反,您需要扩展 ItemDecoration,一个RecyclerView的内部类:

Unlike ListView, the RecyclerView class doesn't have any divider-related parameters. Instead, you need to extend ItemDecoration, a RecyclerView's inner class:

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

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.

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

All ItemDecorations are drawn in the order they were added, before the item views (in onDraw()) and after the items (in onDrawOver(Canvas, RecyclerView, RecyclerView.State).

垂直间距ItemDecoration

扩展ItemDecoration,添加一个自定义构造函数,它以空间height 作为参数并覆盖getItemOffsets() 方法:

Vertical spacing ItemDecoration

Extend ItemDecoration, add a custom constructor which takes space height as a parameter and override the getItemOffsets() method:

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;
}

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

Note: you can also modify outRect.top, outRect.left and outRect.right properties for the desired effect.

扩展 ItemDecoration 并覆盖 onDraw() 方法:

Extend ItemDecoration and override the onDraw() method:

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);
        }
    }
}

您可以调用使用默认 Android 分隔符属性的第一个构造函数,或使用您自己的可绘制对象的第二个构造函数,例如 drawable/divider.xml:

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:

<?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>

注意:如果您希望分隔线覆盖您的项目,请改写 onDrawOver() 方法.

Note: if you want the divider to be drawn over your items, override the onDrawOver() method instead.

要使用您的新类,请将 VerticalSpaceItemDecorationDividerSpaceItemDecoration 添加到 RecyclerView,例如在片段的 onCreateView()代码>方法:

To use your new class, add VerticalSpaceItemDecoration or DividerSpaceItemDecoration to RecyclerView, for example in your fragment's onCreateView() method:

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;
}


还有 Lucas Rocha 的库,旨在简化项目装饰过程.不过我没试过.


There's also Lucas Rocha's library which is supposed to simplify the item decoration process. I haven't tried it though.

功能包括:

  • 一系列库存商品装饰品,包括:
  • 项目间距水平/垂直分隔线.
  • 列表项

这篇关于如何在 RecyclerView 中的项目之间添加分隔线和空格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆