Android Recyclerview的item间距实现

Recyclerview中,提供了一个方法addItemDecoration给我们用于设置item的分割线

下面提供几个常见的分割线效果

注: 下面的SizeUtilsAndroidUtilCode此库里的工具类,需要添加依赖,也可以自行修改封装的方法(主要是将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

作者:Stars-one原文地址:https://www.cnblogs.com/stars-one/p/17845096.html

%s 个评论

要回复文章请先登录注册