获取视图在 GridLayoutManager 上的列号

Jav*_*nça 4 android gridlayoutmanager android-recyclerview recyclerview-layout item-decoration

RecyclerView使用GridLayoutManager具有动态列号的a呈现不同类型的项目。问题是,我有一个RecyclerView.ItemDecoration只适用于让我们说Type A项目。这RecyclerView.ItemDecoration会在左侧列中的那些项目的左侧/开始处添加边距,并在右侧列中的那些项目的右侧/结尾处添加边距。它基本上是为了使项目看起来更居中并因此拉伸(这用于平板电脑/横向模式)。该RecyclerView网格看起来是这样的:

| A | | A |
| A | | A |
   | B |
| A | | A |
| A | | A |
   | B |
| A | | A |
Run Code Online (Sandbox Code Playgroud)

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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 我试图让一个HashMap保持adapterPosition项目的真实位置,即它在适配器上的位置,忽略非type A项目。这还有一些其他问题,我不会详细介绍,但感觉这不是正确的方法。

  • 我尝试的另一件事是检查将应用项目装饰的视图屏幕上的位置(更多向左或向右)。这样做的问题是当这个装饰器运行时视图还没有被渲染。ViewTreeObserver.OnGlobalLayoutListener在视图上添加 a是没有价值的,因为在渲染视图时,项目装饰已经应用,这对视图没有影响。

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

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

有任何想法吗?谢谢

W0r*_*0le 13

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

另外,很抱歉在 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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新。

对于科特林:

val column: Int = (view.layoutParams as GridLayoutManager.LayoutParams).spanIndex
Run Code Online (Sandbox Code Playgroud)