如何在ConcatAdapter中交换两个子适配器,getAdapters返回列表不可变怎么办
关于ConcatAdapter交换子适配器的方案说明
修改源码方案的可行性分析
直接复制ConcatAdapter源码修改内部列表为可变类型的方案不推荐,原因如下:
- 后续官方ConcatAdapter的bug修复、新特性更新无法同步到自定义版本,长期维护成本极高
- ConcatAdapter内部存在大量和子适配器顺序绑定的position计算、变更通知逻辑,直接修改内部列表如果没有同步处理这些逻辑,极容易出现数组越界、item位置计算错误、页面刷新异常等问题,稳定性风险很高
更优的官方原生解决方案
ConcatAdapter本身已经提供了动态调整子适配器顺序的原生API,不需要修改源码也不需要全量替换适配器列表,直接通过removeAdapter()和addAdapter()组合即可实现交换,性能和稳定性都有保证:
// 假设需要交换索引为pos1和pos2的两个子适配器,且pos1 < pos2 List<RecyclerView.Adapter<?>> adapterList = concatAdapter.getAdapters(); RecyclerView.Adapter<?> adapter1 = adapterList.get(pos1); RecyclerView.Adapter<?> adapter2 = adapterList.get(pos2); // 先移除位置靠后的适配器,避免移除靠前适配器导致后序索引偏移 concatAdapter.removeAdapter(adapter2); concatAdapter.removeAdapter(adapter1); // 按交换后的顺序插入回对应位置 concatAdapter.addAdapter(pos1, adapter2); concatAdapter.addAdapter(pos2, adapter1);
该方案的优势:
- 完全基于官方公开API实现,兼容性和稳定性有保障
- ConcatAdapter内部会自动处理对应的item变更通知,只会触发对应范围的局部刷新,不会中断ItemTouchHelper的拖拽动画,在触摸回调中执行也不会有性能问题
- 不需要自己维护适配器列表逻辑,代码简洁易维护
内容的提问来源于stack exchange,提问作者24hg824g2g4gh
相关产品推荐
相关产品推荐

