如何在Android RecyclerView中添加分隔线?

sof*_*n 8 199 android material-design android-recyclerview

我正在开发一个我正在使用的Android应用程序RecyclerView.我需要添加一个分压器RecyclerView.我试着添加 -

recyclerView.addItemDecoration(new
     DividerItemDecoration(getActivity(),
       DividerItemDecoration.VERTICAL_LIST));
Run Code Online (Sandbox Code Playgroud)

下面是我的xml代码 -

   <android.support.v7.widget.RecyclerView
    android:id="@+id/drawerList"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="15dp"
    />
Run Code Online (Sandbox Code Playgroud)

Adi*_*han 257

在2016年10月的更新中,支持库v25.0.0现在具有基本水平和垂直分频器的默认实现!

https://developer.android.com/reference/android/support/v7/widget/DividerItemDecoration.html

 recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL));
Run Code Online (Sandbox Code Playgroud)

  • 而不是`mLayoutManager.getOrientation()`,我使用`DividerItemDecoration.VERTICAL`并且它起作用,因为我的RecyclerView是垂直的. (13认同)
  • 您好,感谢您提供的信息!有没有办法在最后一项之后移除分隔线?我只有一个 CardView,其中实现了 List,底部的 cardview 的分隔符 + 阴影看起来不太好! (4认同)
  • 我遇到了同样的问题,并通过扩展DividerItemDecoration并覆盖getItemOffsets来解决它,然后只有在我不在第一个项目时才调用super.`if(parent.getChildAdapterPosition(view)== state.getItemCount() - 1)`然后返回,否则调用超类'`getItemOffsets()`. (3认同)
  • 有没有办法用这种内置的方式改变分隔线的颜色? (2认同)

N J*_*N J 215

正确的方法是定义ItemDecorationRecyclerView是以下

SimpleDividerItemDecoration.java

public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
    private Drawable mDivider;

    public SimpleDividerItemDecoration(Context context) {
        mDivider = context.getResources().getDrawable(R.drawable.line_divider);
    }

    @Override
    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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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="@color/dark_gray" />

</shape>
Run Code Online (Sandbox Code Playgroud)

最后像这样设置它

recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));
Run Code Online (Sandbox Code Playgroud)

编辑

正如@Alan Solitar指出的那样

context.getResources().getDrawable(R.drawable.line_divider); 
Run Code Online (Sandbox Code Playgroud)

折旧而不是您可以使用的折旧

ContextCompat.getDrawable(context,R.drawable.line_divider);
Run Code Online (Sandbox Code Playgroud)

  • 如果您尝试滑动或移动项目,则会出现此实现的问题. (4认同)
  • 现在不推荐使用context.getResources().getDrawable(R.drawable.line_divider). (3认同)
  • 这完全适合我.但是,我想知道为什么不为这个分隔符添加一个简单的<View>到每个单元格的布局中?它的代码少得多.这种解决方案的性能不是很好吗?TX (3认同)
  • 没问题.这是一个很好的答案,它对我来说非常有用.谢谢. (2认同)

Moh*_*tar 39

如果你想同时拥有水平和垂直分隔线:

  1. 定义水平和垂直分隔线drawables:

    horizo​​ntal_divider.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
      <size android:height="1dip" />
      <solid android:color="#22000000" />
    </shape>
    
    Run Code Online (Sandbox Code Playgroud)

    vertical_divider.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <size android:width="1dip" />
        <solid android:color="#22000000" />
    </shape>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在下面添加以下代码段:

    DividerItemDecoration verticalDecoration = new DividerItemDecoration(recyclerview.getContext(),
            DividerItemDecoration.HORIZONTAL);
    Drawable verticalDivider = ContextCompat.getDrawable(getActivity(), R.drawable.vertical_divider);
    verticalDecoration.setDrawable(verticalDivider);
    recyclerview.addItemDecoration(verticalDecoration);
    
    DividerItemDecoration horizontalDecoration = new DividerItemDecoration(recyclerview.getContext(),
            DividerItemDecoration.VERTICAL);
    Drawable horizontalDivider = ContextCompat.getDrawable(getActivity(), R.drawable.horizontal_divider);
    horizontalDecoration.setDrawable(horizontalDivider);
    recyclerview.addItemDecoration(horizontalDecoration);
    
    Run Code Online (Sandbox Code Playgroud)


小智 29

只需在项目适配器的末尾添加一个View:

<View
 android:layout_width="match_parent"
 android:layout_height="1px"
 android:background="#FFFFFF"/>
Run Code Online (Sandbox Code Playgroud)

  • 使用此解决方案,您还将获得列表末尾的分隔线. (22认同)
  • 最后一行可以通过在onBindViewHolder中说出类似的内容来删除,如果(position == getItemCount() - 1){mDividerView.setVisibility(View.INVISIBLE)}`或者必须有其他方法来执行此操作. (5认同)

gMa*_*ale 25

所有这些答案让我很接近,但每个人都错过了一个关键的细节.经过一些研究,我发现最简单的方法是这3个步骤的组合:

  1. 使用支持库的DividerItemDecoration
  2. 使用正确的颜色创建分隔符
  3. 在主题中将此分隔符设置为listDivider

第1步:配置RecyclerView时

recyclerView.addItemDecoration(
        new DividerItemDecoration(context, layoutManager.getOrientation()));
Run Code Online (Sandbox Code Playgroud)

第2步:在res/drawable/divider_gray.xml等文件中

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <size android:width="1px" android:height="1px" />
    <solid android:color="@color/gray" />
</shape>
Run Code Online (Sandbox Code Playgroud)

第3步:在应用程序的主题中

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Other theme items above -->
    <item name="android:listDivider">@drawable/divider_gray</item>
</style>
Run Code Online (Sandbox Code Playgroud)

编辑:更新以跳过最后一个分隔符:
使用了这一点之后,我意识到它是在最后一个项目之后绘制一个分隔符,这很烦人.所以我按如下方式修改了第1步,以覆盖DividerItemDecoration中的默认行为(当然,另外一个选项是另外一个选项):

recyclerView.addItemDecoration(
        new DividerItemDecoration(context, layoutManager.getOrientation()) {
            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                int position = parent.getChildAdapterPosition(view);
                // hide the divider for the last child
                if (position == parent.getAdapter().getItemCount() - 1) {
                    outRect.setEmpty();
                } else {
                    super.getItemOffsets(outRect, view, parent, state);
                }
            }
        }
);
Run Code Online (Sandbox Code Playgroud)

  • 覆盖getItemOffsets似乎对我不起作用.即使我覆盖并且从不调用超级,仍然会绘制分隔符.不知道改变了什么. (7认同)
  • 它对我也不起作用.最后一个分频器仍在显示. (2认同)

Tob*_*iug 21

以下是简单自定义分隔符的代码(垂直分隔符/ 1dp高度/黑色):

假设您有支持库:

compile "com.android.support:recyclerview-v7:25.1.1"
Run Code Online (Sandbox Code Playgroud)

java代码

    DividerItemDecoration divider = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
    divider.setDrawable(ContextCompat.getDrawable(getBaseContext(), R.drawable.my_custom_divider));
    recyclerView.addItemDecoration(divider);
Run Code Online (Sandbox Code Playgroud)

然后是custom_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>
Run Code Online (Sandbox Code Playgroud)


Gen*_*ani 18

我处理 Divider 视图和 Divider Insets 的方式是添加 RecyclerView 扩展。

1.

通过命名 View 或 RecyclerView 添加一个新的扩展文件:

RecyclerViewExtension.kt
Run Code Online (Sandbox Code Playgroud)

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

2.

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>
Run Code Online (Sandbox Code Playgroud)

在这里你可以指定左,右android:insetLeftandroid:insetRight

3.

在初始化 RecyclerView 的 Activity 或 Fragment 上,您可以通过调用来设置自定义 drawable:

recyclerView.setDivider(R.drawable.recycler_view_divider)
Run Code Online (Sandbox Code Playgroud)

4.

干杯

带分隔线的 RecyclerView 行。


小智 10

res/drawable文件夹中创建一个单独的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>
Run Code Online (Sandbox Code Playgroud)

主活动中连接该xml文件(your_file),如下所示:

DividerItemDecoration divider = new DividerItemDecoration(
    recyclerView.getContext(),
    DividerItemDecoration.VERTICAL
);
divider.setDrawable(ContextCompat.getDrawable(getBaseContext(), R.drawable.your_file));
recyclerView.addItemDecoration(divider);
Run Code Online (Sandbox Code Playgroud)


Viv*_*aru 8

我认为你正在使用FragmentsRecyclerView

只需在创建RecyclerViewLayoutManager对象后添加这些行

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
                DividerItemDecoration.VERTICAL);
        recyclerView.addItemDecoration(dividerItemDecoration);
Run Code Online (Sandbox Code Playgroud)

而已!

它支持HORIZONTAL和VERTICAL方向.


小智 8

试试这个简单的单行代码

recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),LinearLayoutManager.VERTICAL)); 
Run Code Online (Sandbox Code Playgroud)


Dur*_*aco 7

Kotlin版本:

recyclerview.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))
Run Code Online (Sandbox Code Playgroud)


Sma*_*ing 6

所以这可能不是正确的方法,但我只是添加了一个视图到RecyclerView的单项视图(因为我认为没有内置函数),如下所示:

<View
    android:layout_width="fill_parent"
    android:layout_height="@dimen/activity_divider_line_margin"
    android:layout_alignParentBottom="true"
    android:background="@color/tasklist_menu_dividerline_grey" />
Run Code Online (Sandbox Code Playgroud)

这意味着每个项目都有一条填充底部的线条.我用#111111背景制作了大约1dp的高度.这也赋予它一种"3D"效果.

  • -这不是办法 (2认同)

pab*_*rca 6

你需要添加下一行......

mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
Run Code Online (Sandbox Code Playgroud)


Bhu*_* BS 5

您可以创建一个简单的可重用分隔符.

创建分隔符:

public class DividerItemDecorator extends RecyclerView.ItemDecoration {
    private Drawable mDivider;

    public DividerItemDecorator(Drawable divider) {
        mDivider = divider;
    }

    @Override
    public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
        int dividerLeft = parent.getPaddingLeft();
        int dividerRight = 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 dividerTop = child.getBottom() + params.bottomMargin;
            int dividerBottom = dividerTop + mDivider.getIntrinsicHeight();

            mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
            mDivider.draw(canvas);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

创建分隔线: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="@color/grey_300" />
</shape>
Run Code Online (Sandbox Code Playgroud)

将分隔符添加到您的Recyclerview:

RecyclerView.ItemDecoration dividerItemDecoration = new DividerItemDecorator(ContextCompat.getDrawable(context, R.drawable.divider));
recyclerView.addItemDecoration(dividerItemDecoration);
Run Code Online (Sandbox Code Playgroud)

要删除最后一项的分隔符:

要防止最后一项的分隔线绘制,您必须更改此行.

for (int i = 0; i < childCount; i++) 
Run Code Online (Sandbox Code Playgroud)

for (int i = 0; i < childCount-1; i++)
Run Code Online (Sandbox Code Playgroud)

你的最终实现应该是这样的:

public class DividerItemDecorator extends RecyclerView.ItemDecoration {
    private Drawable mDivider;

    public DividerItemDecorator(Drawable divider) {
        mDivider = divider;
    }

    @Override
    public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
        int dividerLeft = parent.getPaddingLeft();
        int dividerRight = parent.getWidth() - parent.getPaddingRight();

        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount - 1; i++) {
            View child = parent.getChildAt(i);

            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

            int dividerTop = child.getBottom() + params.bottomMargin;
            int dividerBottom = dividerTop + mDivider.getIntrinsicHeight();

            mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom);
            mDivider.draw(canvas);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你:)