我使用具有动态列号的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
,因此根据TabletGridSpaceItemDecoration
,应在右边添加空白,这是不正确的。我尝试使用
HashMap
来保留adapterPosition
和项目的实际位置,即忽略不包含type A
项目的适配器上的位置。这还有其他一些问题,我不会在细节上过多介绍,但是它没有正确的方法。我尝试的另一件事是检查视图屏幕在屏幕上的位置(向左或向右),将应用项目装饰。问题在于运行该装饰器时尚未渲染视图。在视图上添加
ViewTreeObserver.OnGlobalLayoutListener
是毫无用处的,因为在渲染视图时,项目装饰已被应用,这对视图没有影响。我要检查的是项目是否在“第0列”或“第1列”中,并相应地增加边距。
我不知道这是怎么可能的,并且在查看
GridLayoutManager
提供的内容(也可以通过parent.layoutManager as GridLayoutManager
进行访问)时,没有找到解决方法。有任何想法吗?谢谢
最佳答案
我将其分享为答案,因为评论太长了。让我知道结果,然后删除,如果不起作用。
另外,很抱歉分享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
}
}
}
关于android - 获取在GridLayoutManager上 View 所在的列号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56775671/