默認效果是這樣
期望的效果是這樣
期望是每一行類似ConstraintLayout中的chain spread inside
第一個居左菇绵,最后一個居右肄渗,中間的每一個都居中平分剩余的空間
虛線是GridLayoutManger 默認的每個item的left
怎么實現(xiàn)呢,了解一下下面的計算細則咬最?
- 默認虛線的位置是spanIndex*spanWidth
- 期望的item.left=默認虛線的位置+ItemDecoration.left
所以通過設置itemDecoration.left 就可以完成
下面直接給出計算的代碼
private class AverageGridItemDecoration : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
val layoutManager = parent.layoutManager as? GridLayoutManager ?: return
val spanCount = layoutManager.spanCount
val parentWidth = parent.measuredWidth - parent.paddingStart - parent.paddingEnd
// 每一條的寬度的獲取翎嫡,我這里是直接寫死了一個值.
// 當然你也可以動態(tài)計算或者測量出來,但是不能直接使用view.getWidth(),因為此時有可能還沒有完成布局
val itemWidth = view.resources.getDimension(R.dimen.course_practice_result_item_size)
val spanWidth = parentWidth / spanCount
if (spanCount == 1) return
val spanMargin = (parentWidth - itemWidth * spanCount) / (spanCount - 1)
val spanSizeLookup = layoutManager.spanSizeLookup
val adapterPosition = parent.getChildAdapterPosition(view)
val columnIndex = spanSizeLookup.getSpanIndex(adapterPosition, spanCount)
// 核心代碼:
// 左邊的間距 = 期望的left- 默認的left
outRect.left =
((itemWidth + spanMargin) * columnIndex - spanWidth * columnIndex).toInt()
// 不是第一行的情況永乌,設置上邊距
if (spanSizeLookup.getSpanGroupIndex(adapterPosition, spanCount) > 0) {
outRect.top = dp2px(15f).toInt()
}
}
}