我有不同类型的项目在使用GridLayoutManager以动态列数的方式呈现在RecyclerView中。问题是,我有一个RecyclerView.ItemDecoration仅适用于某些类型A的项目。该RecyclerView.ItemDecoration对于左侧列上的这些项目添加了左/开始边缘的间距,并对右侧列上的这些项目添加了右/结束边缘的间距。它基本上是为了使项目看起来更加居中和伸展(这在平板电脑/横向模式上使用)。RecyclerView网格看起来像这样:
"
这个装饰器的问题在于,列表中第一个
我尝试使用
我尝试的另一件事是检查视图(更靠左还是更靠右)上要应用项装饰的位置。但问题在于当运行此装饰器时,视图尚未呈现。在视图上添加
我想做的是检查项目是否在“列0”或“列1”中,并相应地添加边距。
我不知道如何做到这一点,并且在查看可通过
有什么想法吗?谢谢。
| 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”中,并相应地添加边距。
我不知道如何做到这一点,并且在查看可通过
parent.layoutManager as GridLayoutManager
访问的 GridLayoutManager
所提供的内容时也没有找到方法。有什么想法吗?谢谢。
LayoutParams
中获取跨度。运行得很好,谢谢! - Javier Mendonça