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()
}
}