设置StaggeredGridLayoutManager的gapStrategy导致View不可见求助
解决StaggeredGridLayoutManager双列布局顺序错乱问题
你的问题出在StaggeredGridLayoutManager的布局逻辑上——它是瀑布流布局,核心是根据item高度自动填充间隙,即便设置GAP_HANDLING_NONE,整宽item(占2列)也会打乱后续普通item的列排序,无法保证严格的左A/C/E/G、右B/D/F/H的线性排列。
最优解决方案:改用GridLayoutManager
GridLayoutManager是专为网格布局设计的,支持通过SpanSizeLookup精准控制不同item的列跨度,完全匹配你的需求:
fun bindRV() { val layoutManager = GridLayoutManager(context, 2, RecyclerView.VERTICAL, false) // 自定义跨度规则:分区item占满2列,普通item占1列 layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { override fun getSpanSize(position: Int): Int { val item = serviceViewModel.getServiceBlockItems()[position] // 替换成你实际判断分区item的逻辑,比如根据item类型 return if (item is SectionItem) 2 else 1 } } recyclerViewServicesBlock.layoutManager = layoutManager serviceBlockAdapter.items = serviceViewModel.getServiceBlockItems() recyclerViewServicesBlock.adapter = serviceBlockAdapter }
如果坚持用StaggeredGridLayoutManager(不推荐)
需要在Adapter中手动控制每个普通item的列索引,同时要计算分区item对位置的影响:
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { val item = items[position] val layoutParams = holder.itemView.layoutParams as StaggeredGridLayoutManager.LayoutParams if (item is NormalItem) { layoutParams.isFullSpan = false // 计算去掉分区item后的实际索引,用来确定列位置 val normalItemIndex = items.subList(0, position).count { it !is SectionItem } // 偶数索引放左列(0),奇数放右列(1) layoutParams.setSpanIndex(normalItemIndex % 2, 2) } else { layoutParams.isFullSpan = true } }
这种方法需要额外处理位置偏移,容易出现边界错误,远不如GridLayoutManager可靠。
内容的提问来源于stack exchange,提问作者Rafael
相关产品推荐
相关产品推荐

