RecyclerView使用GridLayoutManager实现2列等分布局及item间距调整问题
GridLayoutManager 2列均等宽加间距修复方案
问题核心诱因
- 多余的span配置:你当前设置总span数为4、每个item占2span的实现虽然能达到2列效果,但属于冗余配置,直接设总span为2更合理
- item固定宽度配置错误:GridLayoutManager会自动根据span数分配item宽度,你设置固定宽度会挤占正常的间隔空间,导致横向间隔异常
- 未添加间距装饰:RecyclerView默认不会给item添加任何间距,需要通过
ItemDecoration自定义实现横向、纵向间距
具体修复步骤
- 简化GridLayoutManager配置
直接设置总span数为2即可,不需要额外配置spanSizeLookup:
val manager = GridLayoutManager(this, 2) recycler.layoutManager = manager
- 修改item布局参数
item根布局的宽度必须设置为match_parent,高度根据业务需求设为wrap_content或者固定数值即可,禁止设置固定宽度:
<!-- item布局根节点示例 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="120dp" android:background="@color/white" android:orientation="vertical"> <!-- 子视图内容 --> </LinearLayout>
- 自定义ItemDecoration实现均匀间距
首先实现通用的网格布局间距装饰类:
class GridSpacingItemDecoration( private val spanCount: Int, // 列数 private val spacing: Int, // 间距大小(单位px) private val includeEdge: Boolean // 是否包含屏幕左右、上下边缘的间距 ) : RecyclerView.ItemDecoration() { override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) { val position = parent.getChildAdapterPosition(view) val column = position % spanCount if (includeEdge) { outRect.left = spacing - column * spacing / spanCount outRect.right = (column + 1) * spacing / spanCount if (position < spanCount) { // 第一行顶部加间距 outRect.top = spacing } outRect.bottom = spacing // 底部间距 } else { outRect.left = column * spacing / spanCount outRect.right = spacing - (column + 1) * spacing / spanCount if (position >= spanCount) { outRect.top = spacing // 非第一行顶部加间距 } } } }
然后给RecyclerView添加装饰:
// 先在res/values/dimens.xml中定义间距,比如8dp // <dimen name="grid_item_spacing">8dp</dimen> val spacing = resources.getDimensionPixelSize(R.dimen.grid_item_spacing) recycler.addItemDecoration(GridSpacingItemDecoration(2, spacing, true))
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

