You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为高度不一的无限滚动RecyclerView添加居中背景黑线?

最优方案:使用RecyclerView.ItemDecoration实现

嘿,这个需求我熟得很!要在高度不一的RecyclerView列表项底部中间加黑线,还得性能拉满?RecyclerView.ItemDecoration绝对是最优解,没有之一。下面给你拆解下为什么以及怎么实现:

为什么选ItemDecoration?

这是RecyclerView原生提供的装饰扩展,专门用来处理分割线、间距这类UI装饰,优势太明显了:

  • 完全不侵入item布局,不用给每个item额外加View,避免了布局层级冗余,减少Measure/Layout阶段的性能开销
  • 统一在RecyclerView的绘制流程中处理装饰,比每个item单独绘制高效得多,尤其适合无限滚动这种大量item的场景
  • 灵活可控,能轻松调整黑线的显示规则(比如不给最后一个item加线)

具体实现步骤

1. 自定义ItemDecoration类

我们要写一个继承自RecyclerView.ItemDecoration的类,负责计算间距并绘制中间黑线:

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.RecyclerView

class MiddleBottomLineDecoration(
    private val lineWidth: Int,    // 黑线的宽度(比如100dp)
    private val lineHeight: Int,   // 黑线的高度(比如2dp)
    private val lineColor: Int = Color.BLACK
) : RecyclerView.ItemDecoration() {

    // 给item底部留出黑线的高度,防止黑线被item内容覆盖
    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        super.getItemOffsets(outRect, view, parent, state)
        outRect.bottom = lineHeight
    }

    // 绘制中间黑线
    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(c, parent, state)
        val childCount = parent.childCount
        val paint = Paint().apply {
            color = lineColor
            style = Paint.Style.FILL
            isAntiAlias = true // 抗锯齿,让线条更平滑
        }

        // 遍历每个可见的item,绘制对应的黑线
        for (i in 0 until childCount) {
            val child = parent.getChildAt(i)
            val params = child.layoutParams as RecyclerView.LayoutParams

            // 计算黑线的位置:水平居中,宽度为lineWidth,位于item底部(包含margin)
            val lineLeft = (parent.width - lineWidth) / 2f
            val lineRight = lineLeft + lineWidth
            val lineTop = child.bottom + params.bottomMargin.toFloat()
            val lineBottom = lineTop + lineHeight

            // 绘制矩形黑线
            c.drawRect(lineLeft, lineTop, lineRight, lineBottom, paint)
        }
    }
}

2. 给RecyclerView添加装饰

在初始化RecyclerView的地方,把这个Decoration加进去就行:

// 从资源文件读取尺寸(推荐,方便适配)
val lineWidth = resources.getDimensionPixelSize(R.dimen.middle_line_width)
val lineHeight = resources.getDimensionPixelSize(R.dimen.middle_line_height)

// 添加装饰
recyclerView.addItemDecoration(MiddleBottomLineDecoration(lineWidth, lineHeight))

3. 可选:控制黑线的显示规则

如果不想给最后一个item加黑线,只需要在onDraw里加个判断:

// 获取当前可见item的位置
val position = parent.getChildAdapterPosition(child)
// 如果是最后一个item,跳过绘制
if (position == parent.adapter?.itemCount?.minus(1)) {
    continue
}

为什么不推荐其他方案?

  • 在item布局里加View:每个item多一个View,会增加内存占用和绘制开销,尤其无限滚动时,大量重复的View会拖慢性能
  • 自定义RecyclerView:需要修改RecyclerView的绘制逻辑,复杂度高,完全没必要,原生ItemDecoration已经能完美解决

内容的提问来源于stack exchange,提问作者Tobias von Falkenhayn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:44:30