如何给RecycleView 设置间隔?

本文总结了RecycleView设置间隔的三种方法:在item布局中设置、自定义ItemDecoration通过Rect设置和使用onDraw绘制。分别探讨了每种方法的实现原理、效果以及适用场景,帮助开发者更好地理解和选择合适的间隔设置方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

网上设置RecycleView间隔的几种方法总结

  1. item布局中,设置间隔
  2. 自定义ItemDecoration 实现间隔,又分为两种:
    2.1 使用Rect 设置left、top 、right 、bottom 设置间距,伪造间隔
    2.2 使用draw 绘制间隔(onDraw、onDrawOver)
  3. 官方默认的分割线
    三种方法,无优劣之分,各有适用的场景。

方法对比

1.item布局设置分割线
1.1 顶部带分割线(LinearLayoutManager.VERTICAL)
效果

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <!--分割线-->
    <View
        android:layout_width="match_parent"
        android:layout_height="3dp"
        android:background="#FFFFFF" />

    <ImageView
        android:id="@+id/img_item"![在这里插入图片描述](https://img-blog.csdnimg.cn/20190712210659517.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTMwNDA4MTk=,size_16,color_FFFFFF,t_70)
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:background="@color/colorPrimary" />

</LinearLayout>

1.2 顶部无间距(LinearLayoutManager.VERTICAL)
效果


在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/img_item"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:background="@color/colorPrimary" />
    <!--分割线-->
    <View
        android:layout_width="match_parent"
        android:layout_height="3dp"
        android:background="#FFFFFF" />

</LinearLayout>

1.3分割线左右间距(LinearLayoutManager.VERTICAL)
效果


在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/img_item"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:background="@color/colorPrimary" />
    <!--分割线 设置margin-->
    <View
        android:layout_width="match_parent"
        android:layout_height="3dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:background="#680707" />
</LinearLayout>

如果是LinearLayoutManager.HORIZONTAL,思路是一样。啰啰嗦嗦的。。。


在这里插入图片描述

2.自定义ItemDecoration设置分割线
说道ItemDecoration不得不说三个方法:


	/**
	 * @param c 画布
	 * @param parent RecyleView
	 * @param state RecyclerView的当前状态
	 */
	@Override
	public void onDraw(Canvas c, RecyclerView parent,RecyclerView.State state) {
/**
	 * @param outRect  
	 * @param view  RecycleView的itemView
	 * @param parent  RecycleView 
	 * @param state  RecycleView 的状态
	 */
	@Override
	public void getItemOffsets(Rect outRect,View view, RecyclerView parent, RecyclerView.State state)
	/**
	 * @param c 画布
	 * @param parent RecycleView 
 	 * @param state  RecycleView的状态
	 */
	@Override
	public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) 

至于这三者的功能,您可以看下别人写的的博客(感谢,借用他的图),比较直观
onDrawOver和onDraw的区别
有个图比较的直观的在这里插入图片描述

你还记的上面说的2.1、2.2 两种不同的分割线的方法吗?
就和onDraw()和getItemOffsets()方法有关。下面我们细细说来:

  • 使用Rect 来设置间隔
    Rect 到底是什么 ,还是上一张图(借个图,感谢作者)比较直观些。
    在这里插入图片描述
    其中绿色View 是RecycleView的item(手机上显示的item,就是绿色的部分);
    外部橘色是 在Rect 设置了left 、top、righ 、bottom 后的间距,默认情况下let、top、right、bottom都是0。
    Rect.left相当于 marginleft,其他类似。
    View 设置了Rect 后,会有类似Margin的属性(是类似),在空间不够的情况下,可能会出现view被压缩 等情况。尤其在网格布局中。
    这种设置Rect的方法,并不算是真正的设置分割线,而是利用了设置margin的间距,利用recycleView的 背景颜色作为分隔线,所有分割线的长度(高度)不可控:

  • 分割线长度:由recycleView得长度控制

  • 分割线高度:由前一个item的rect.bottom +当前item的rect.top= 分割线的高度
    效果:如下图
    在这里插入图片描述
    具体:黄色是recycleView的背景颜色;recycleView 的item 是上图中的
    在这里插入图片描述
    整个的item的背景是白色,特意设置imgView 的高度不填充item 。左右的黄色的间隔是由于设置rect.left/rect.right 。
    具体的代码:
    item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:background="@android:color/white"
    android:gravity="center_vertical">

    <ImageView
        android:id="@+id/img"
        android:layout_width="match_parent"
        android:layout_height="60dp" />
</LinearLayout>

自定义LinearItemDecoration

	@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.getChildPosition(view) == 0)
//			outRect.top = space;
	}
  • 使用onDraw()来绘制间隔
    分层图中,可以明显的看出来,onDraw() 绘制的面板 在itemView的下面。使用draw()即使绘制了分割线,但是由于ItemView的遮盖,还是显示不出来,所以:自定义分割线,需要使用到Rect 方法,控制item的间隔提供空间来显示绘制的分割线。我们需要获取item之间的间距,计算分割线的四个关键点坐标,绘制矩形。
    效果:
    在这里插入图片描述具体代码
@Override
	public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
		int count = parent.getChildCount(); //recycleView中item显示在界面的个数
		for (int i = 0; i < count; i++) {
			View childView = parent.getChildAt(i); // 获取position的item
			int index = parent.getChildAdapterPosition(childView); // 获取itemView所在的位置
			if (index != 0) {
				ViewGroup.MarginLayoutParams childLp = (ViewGroup.MarginLayoutParams) ((ViewGroup) childView)
						.getChildAt(0).getLayoutParams(); //获取itemView中ImageView的margin值
				int devideLeft = childLp.leftMargin; // 设置矩形left
				int rectMiddleLine = 30 / 2; // 分割线一半的高度
				int topLine = childView.getTop() - rectMiddleLine - devideHeight / 2;
				int devideTop = topLine;   // 设置分割线的top
				int devideRight = parent.getWidth() - childLp.rightMargin; // 设置矩形right
				int devideBottom = childView.getTop() - rectMiddleLine + devideHeight / 2;   // 设置分割线的bottom
				c.drawRect(devideLeft, devideTop, devideRight, devideBottom, paint); // 绘制分割线矩形
			}
		}
	}

	@Override
	public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
		super.getItemOffsets(outRect, view, parent, state);
		if (parent.getChildAdapterPosition(view) != 0) {
			outRect.top = 30;  // item之间的距离
			devideHeight = 10; // 自绘制的间距的矩形的高度
		}
	}

其中红色的是我们自己绘制的分割线,黄色的还是recycleView的背景颜色,白色是itemView的背景颜色。

  • 使用onDrawOver绘制
    方法和onDrawOver类似,只不过是绘制在itemView上层。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值