我使用具有动态列号的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
所提供的内容中也找不到解决方法。
有什么想法吗?谢谢
答案 0 :(得分:1)
我将其作为答案,因为评论太久了。让我知道结果,然后,如果不起作用,则删除。
此外,很抱歉分享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
}
}
}