首页 > 解决方案 > 获取视图在 GridLayoutManager 上的列号

问题描述

RecyclerView我使用GridLayoutManager带有动态列号的方式呈现不同类型的项目。问题是,我有一个RecyclerView.ItemDecoration要申请的,比如说Type A项目。这RecyclerView.ItemDecoration将向左侧/开始添加左侧列上的那些项目的边距,并在右侧列上的那些项目的右侧/结束处添加边距。这基本上是为了使项目看起来更居中,因此被拉伸(这用于平板电脑/横向模式)。RecyclerView网格看起来像这样:

| A | | A |
| A | | A |
   | B |
| A | | A |
| A | | A |
   | B |
| A | | A |

ItemDecoration看起来像这样:

class TabletGridSpaceItemDecoration(private val space: Int) : RecyclerView.ItemDecoration() {

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) = with(outRect) {
        val isTypeAItemLayout = view.findViewById<ConstraintLayout>(R.id.type_a_item_container) != null

        if (isTypeAItemLayout) {
            val adapterPosition = parent.getChildAdapterPosition(view)

            if (adapterPosition % 2 == 0) {
                left = space
                right = 0
            } else {
                left = 0
                right = space
            }
        }
    }
}

这个装饰器的问题是,在type B列表中的第一个项目之后,下一个项目的索引被搞砸了type A。所以根据提供的示例后的第一项B会有adapterPosition == 5,所以根据TabletGridSpaceItemDecorationmarging应该添加到右边,这是不正确的。

我想做的是检查一个项目是否在“第 0 列”或“第 1 列”中,并相应地添加边距。

我不知道这怎么可能,也没有找到方法来查看GridLayoutManager提供的内容,可以通过parent.layoutManager as GridLayoutManager.

有任何想法吗?谢谢

标签: androidandroid-recyclerviewrecyclerview-layoutgridlayoutmanageritem-decoration

解决方案


我将其作为答案分享,因为评论太长了。让我知道结果,然后,如果不起作用,我将删除。

另外,很抱歉分享Java ..我对Kotlin不识字

而不是使用位置,您可以尝试使用spanIndex

@Override
public void getItemOffsets(final Rect outRect, final View view, final RecyclerView parent, final State state) {
    ... 
    if(isTypeAItemLayout) {
        int column = ((GridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex();
        if (column == 0) {
            // First Column
        } else {
            // Second Column
        }
    }
}

更新。

对于科特林:

val column: Int = (view.layoutParams as GridLayoutManager.LayoutParams).spanIndex

推荐阅读