安卓Recyclerview的GridLayoutManager列间距问题

322

如何使用GridLayoutManager设置RecyclerView的列间距?在布局内设置margin/padding没有效果。


你尝试过继承GridLayoutManager并重写generateDefaultLayoutParams()及其相关方法吗? - CommonsWare
我之前没有想到可以设置网格视图的间距,可能是我没发现相关方法。我会尝试一下。 - Nick H
https://dev59.com/U1sW5IYBdhLWcg3wQVb2#35226600 - hch
尝试一下这个 https://gist.github.com/Arpit0492/cf14df02ddf53741df5dde864002e89c - Arpit J.
33个回答

0

这是最终对我起作用的代码:

binding.rows.addItemDecoration(object: RecyclerView.ItemDecoration() {
    val px = resources.getDimensionPixelSize(R.dimen.grid_spacing)
    val spanCount = 2

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        val index = parent.getChildLayoutPosition(view)
        val isLeft = (index % spanCount == 0)
        outRect.set(
            if (isLeft) px else px/2,
            0,
            if (isLeft) px/2 else px,
            px
        )
    }
})

因为我只有两列 (val spanCount = 2),所以我只需要 isLeft。如果有超过两列,那么我还需要一个 isMiddle,并且两侧的值都将是 px/2

我希望能够直接从 RecyclerView 中获取 app:spanCount,但我不认为这是可能的。


0
如果您正在使用 GridLayoutManagerHeader,请使用以下 Kotlin 代码来设置网格之间的间距:
inner class SpacesItemDecoration(itemSpace: Int) : RecyclerView.ItemDecoration() {

    var space: Int = itemSpace

    override fun getItemOffsets(outRect: Rect?, view: View?, parent: RecyclerView?, state: RecyclerView.State?) {
        super.getItemOffsets(outRect, view, parent, state)
        val position = parent!!.getChildAdapterPosition(view)
        val viewType = parent.adapter.getItemViewType(position)
        
        // Check to not to set any margin to header item 
        if (viewType == GridViewAdapter.TYPE_HEADER) {
            outRect!!.top = 0
            outRect.left = 0
            outRect.right = 0
            outRect.bottom = 0
        } else {
            outRect!!.left = space
            outRect.right = space
            outRect.bottom = space

            if (parent.getChildLayoutPosition(view) == 0) {
                outRect.top = space
            } else {
                outRect.top = 0
            }
        }
    }
}

ItemDecoration传递给RecyclerView

gridView.addItemDecoration(SpacesItemDecoration(10))

最好使用 Elvis 运算符 (?:) 而不是 !! - SerjantArbuz

-1

感谢edwardaa的回答https://dev59.com/E14b5IYBdhLWcg3w7Fcv#30701422

另外需要注意的一点是:

如果总间距和总itemWidth不等于屏幕宽度,您还需要在适配器的onBindViewHolder方法中调整itemWidth。

Utils.init(_mActivity);
int width = 0;
if (includeEdge) {
    width = ScreenUtils.getScreenWidth() - spacing * (spanCount + 1);
} else {
    width = ScreenUtils.getScreenWidth() - spacing * (spanCount - 1);
}
int itemWidth = width / spanCount;

ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) holder.imageViewAvatar.getLayoutParams();
// suppose the width and height are the same
layoutParams.width = itemWidth;
layoutParams.height = itemWidth;
holder.imageViewAvatar.setLayoutParams(layoutParams);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接