Android开发小技巧:GridLayoutManager如何正确的增加条目之间的间隙

14 阅读1分钟

GridLayoutManager增加间隙很奇怪,假如有三列,第一列左边距0dp,第三列右边距0dp,列之间的间隙为12dp,如果简单的通过设置第一列left=0dp,right=6dp,第二列left=6dp,right=6dp,第三列left=6dp,right=0dp,实现的效果并不能满足实际需求。这是因为6dp 是固定值,但 RecyclerView 的可用宽度(屏幕宽度 - padding)是动态的。如果总列宽和间隙的累加值与屏幕宽度不匹配,会导致:

  • 间隙过大​:列宽被挤压,内容显示不全。
  • 间隙过小​:右侧出现空白,无法对齐边缘。

所以通过 ​比例分配​ 或 ​公式化动态计算,让总间隙和列宽自动适配屏幕宽度:

import android.annotation.SuppressLint
import android.graphics.Canvas
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager

import androidx.recyclerview.widget.RecyclerView
import com.abc.abc.infra.common.kts.dp2px
import com.abc.abc.infra.common.kts.dp2pxInt


/**
 * RecyclerView间距
 * @param leftRight 传dp值
 * @param top 传dp值
 * @param bottom 传dp值
 * @param rowNum 一排几个
 */
class CommonGridItemDecoration(
    private val leftRight: Int,
    private val top: Int,
    private val bottom: Int,
    private val rowNum: Int
) : RecyclerView.ItemDecoration() {
    //leftRight为横向间的距离 topBottom为纵向间距离

    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(c, parent, state)
    }

    @SuppressLint("WrongConstant")
    override fun getItemOffsets(
        outRect: Rect,
        view: View,
        parent: RecyclerView,
        state: RecyclerView.State
    ) {
        val position = parent.getChildAdapterPosition(view)
        val leftRightPx = leftRight.toFloat().dp2px.toInt()
        val topPx = top.toFloat().dp2px.toInt()
        val bottomPx = bottom.toFloat().dp2px.toInt()
        //头部
        outRect.top = topPx
        //底部
        outRect.bottom = bottomPx
        //左右
        val positionInLine = position % rowNum // 行内位置
        if (positionInLine == 0) {
            outRect.left = 0
        } else {
            outRect.left = (positionInLine * 1f * leftRightPx / rowNum).toInt()
        }
        outRect.right = ((rowNum - positionInLine - 1) * 1f * leftRightPx / rowNum).toInt()
    }

}