Android Recyclerview的item间距实现
Recyclerview中,提供了一个方法addItemDecoration
给我们用于设置item的分割线
下面提供几个常见的分割线效果
注: 下面的
SizeUtils
是AndroidUtilCode此库里的工具类,需要添加依赖,也可以自行修改封装的方法(主要是将dp单位转为px)
以下代码已封装在我的库中stars-one/XAndroidUtil: 封装自己常用的一些Android的组件或工具,可以直接依赖使用
注意库中的类名与本文例子有所变化,自行参考库的文档说明
Linearlayout垂直排列每个item间隔
效果
代码
/**
*
* @param space 间距(单位px)
*/
class VerticalItemDecoration(val space: Int = SizeUtils.dp2px(12f)) :
RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val position = parent.getChildAdapterPosition(view)
val allCount = parent.adapter?.itemCount ?: 0
//最后一个不加边距
if (position == allCount - 1) {
return
}
outRect.bottom = space
}
}
上面代码实际就是在每个item后面添加一个间隔(最后一个则不加间隔)
PS: 实际上,这种简单的可以直接在item的布局添加一个margin也可以实现
GridLayoutManager(类似九宫格布局)
UI的要求九宫格布局,需要中间有间隔,然后每行的几个item的宽度需要平分该行剩余空间大小(除去间距)
效果
代码
/**
*
* @param spanCount 每行的item数目
* @param space 间隔(单位px)
*/
class GridItemDecoration(val spanCount: Int = 3, val space: Int = SizeUtils.dp2px(8f)) :
RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val position = parent.getChildAdapterPosition(view)
val column = position % spanCount
outRect.left = column * space / spanCount;
outRect.right = space - (column + 1) * space / spanCount
//item的上边距,这里各位根据需求自己修改,也可以设置下边距
if (position >= spanCount) {
outRect.top = space
}
}
}
为了方便在外层直接设置上下边距,对上面的代码新增一个参数
/**
*
* @param spanCount 每行的item数目
* @param space 间隔(单位px)
*/
class GridItemDecoration(
val spanCount: Int = 3,
val space: Int = SizeUtils.dp2px(8f),
val action: ((outRect: Rect, space: Int, position: Int) -> Unit)? = null
) :
RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val position = parent.getChildAdapterPosition(view)
val column = position % spanCount
outRect.left = column * space / spanCount;
outRect.right = space - (column + 1) * space / spanCount
//上边距,这里各位根据需求自己修改
if (position >= spanCount) {
outRect.top = space
action?.invoke(outRect, space, position)
}
}
}
//使用
val itemDero = GridItemDecoration {outRect, space, position -> }
mrecyclerview.addItemDecoration(itemDero)
补充
网格布局根据orientation从而展示item的顺序不同
GridLayoutManager(context, 2).apply {
orientation = RecyclerView.VERTICAL
}
如果是Vertical,则是一行行排列,一行满足了spanCount则自动换行,如下面效果:
1 2
3 4
如果是HORIZONTAL,则是与一列列排列,每列满足了spanCount则自动换行,如下面效果
1 3
2 4