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

RecyclerView中移除最后一行空白列的多余Item Decoration

解决RecyclerView最后一行空白列的分割线问题

方法一:修正SpanSizeLookup+自定义分割线

你的原有SpanSizeLookup逻辑存在计算漏洞(当item总数能被10整除时,lastRowCount会等于0,导致判断失效),同时默认DividerItemDecoration会给空白列也添加分割线,需要结合修正布局逻辑和自定义分割线来解决:

1. 修正GridLayoutManager的SpanSizeLookup

val manager = GridLayoutManager(context, 10)
manager.spanSizeLookup = object : SpanSizeLookup() {
    override fun getSpanSize(position: Int): Int {
        val totalItems = taskDatesAdapter.itemCount
        val itemsInLastRow = totalItems % 10
        // 处理总数能被10整除的情况,最后一行仍为10个item
        val lastRowItemCount = if (itemsInLastRow == 0) 10 else itemsInLastRow
        val isLastRow = position >= totalItems - lastRowItemCount
        // 所有item都保持1格宽度,仅修正布局判断逻辑
        return 1
    }
}
taskDatesView.layoutManager = manager

2. 自定义分割线跳过最后一行空白列

替换默认的DividerItemDecoration,只给有效item添加分割线:

class CustomGridDividerDecoration(
    context: Context,
    orientation: Int,
    private val spanCount: Int
) : RecyclerView.ItemDecoration() {
    private val dividerDrawable: Drawable?

    init {
        val a = context.obtainStyledAttributes(intArrayOf(android.R.attr.listDivider))
        dividerDrawable = a.getDrawable(0)
        a.recycle()
    }

    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        super.getItemOffsets(outRect, view, parent, state)
        val position = parent.getChildAdapterPosition(view)
        val totalItems = state.itemCount.takeIf { it > 0 } ?: return

        val itemsInLastRow = totalItems % spanCount
        val lastRowItemCount = if (itemsInLastRow == 0) spanCount else itemsInLastRow
        val isLastRow = position >= totalItems - lastRowItemCount

        // 水平方向:最后一行的最后一个item不添加右侧分割线
        if (orientation == DividerItemDecoration.HORIZONTAL) {
            outRect.right = if (isLastRow && position == totalItems - 1) 0 else dividerDrawable?.intrinsicWidth ?: 0
        }
    }

    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(c, parent, state)
        if (orientation != DividerItemDecoration.HORIZONTAL || dividerDrawable == null) return

        val childCount = parent.childCount
        for (i in 0 until childCount) {
            val child = parent.getChildAt(i)
            val position = parent.getChildAdapterPosition(child)
            val totalItems = parent.adapter?.itemCount ?: 0
            if (totalItems == 0) return

            val itemsInLastRow = totalItems % spanCount
            val lastRowItemCount = if (itemsInLastRow == 0) spanCount else itemsInLastRow
            val isLastRow = position >= totalItems - lastRowItemCount

            // 最后一行的最后一个item不绘制分割线
            if (isLastRow && position == totalItems - 1) continue

            val params = child.layoutParams as RecyclerView.LayoutParams
            val top = child.top - params.topMargin
            val bottom = child.bottom + params.bottomMargin
            val left = child.right + params.rightMargin
            val right = left + dividerDrawable.intrinsicWidth
            dividerDrawable.setBounds(left, top, right, bottom)
            dividerDrawable.draw(c)
        }
    }
}

然后替换原有分割线代码:

// 移除默认分割线
// taskDatesView.addItemDecoration(decoration)
// 添加自定义分割线
val customDecoration = CustomGridDividerDecoration(context, DividerItemDecoration.HORIZONTAL, 10)
taskDatesView.addItemDecoration(customDecoration)

方法二:让最后一行item填满整行(无空白列)

如果需求是让最后一行的item自动扩展宽度填满整行,直接修改SpanSizeLookup即可:

manager.spanSizeLookup = object : SpanSizeLookup() {
    override fun getSpanSize(position: Int): Int {
        val totalItems = taskDatesAdapter.itemCount
        val itemsInLastRow = totalItems % 10
        if (itemsInLastRow == 0) return 1
        
        val isLastRow = position >= totalItems - itemsInLastRow
        // 最后一行的每个item占对应比例的宽度,填满整行
        return if (isLastRow) 10 / itemsInLastRow else 1
    }
}

内容的提问来源于stack exchange,提问作者Manju

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 23:36:22