Android Kotlin 服务端列表设置给RecyclerView Adapter前更新,删除仅修改指定商品
问题原因
- 你当前对本地数据库的监听是全量删除记录查询
mainLocalViewModel.getAllDeletedItems(),只要删除表内任意数据变动,都会返回所有已删除商品的记录,触发全量遍历更新。 - 每次Observer回调时都会清空整个列表再重新添加服务端数据,再遍历所有已删除条目匹配所有列表商品,所有匹配上的商品都会调用
notifyItemChanged刷新,最终表现为所有商品数量都被更新。 - 嵌套循环的匹配逻辑效率低下,也容易引发不必要的全局刷新。
修复方案
1. 拆分初始化和单次删除的逻辑
- 只有页面首次加载商品列表、或者服务端全量列表刷新时,才调用全量删除记录查询做一次性的列表数量校准
- 用户点击删除单个商品时,不要走全量查询的回调逻辑,单独处理当前删除的商品即可
2. 优化全量校准逻辑
把已删除记录转成哈希表查找,避免嵌套循环,仅在需要全量校准的时候执行一次:
// 仅在首次加载/服务端列表刷新时调用该方法 fun initOrderList() { val deletedMap = mainLocalViewModel.getAllDeletedItems().value?.associate { it.itemId to it.deletedItems } ?: emptyMap() viewModel.customerOrdersList = viewModel.serverCustomerOrderList.map { serverItem -> val deletedCount = deletedMap[serverItem.itemId] ?: 0 serverItem.copy(itemTotal = serverItem.itemTotal?.minus(deletedCount)) } as MutableList<OrderItemModel> if (!::customerOrdersAdapter.isInitialized) { customerOrdersAdapter = CustomerOrdersAdapter(requireContext(), viewModel.customerOrdersList, this) binding.recyclerViewCustomerOrder.apply { layoutManager = GridLayoutManager(requireContext(), 2) adapter = customerOrdersAdapter } } else { customerOrdersAdapter.notifyDataSetChanged() } }
3. 单独处理用户删除操作
// 用户点击删除按钮的回调 fun onDeleteClick(item: OrderItemModel, position: Int) { // 1. 把删除数据存入本地数据库 val deletedItem = DeletedItemModel( itemId = item.itemId, customerId = viewModel.customerId, deletedItems = 1 // 替换为实际要删除的数量 ) mainLocalViewModel.insertDeletedItem(deletedItem) // 2. 直接更新当前位置的商品数量 val currentItem = viewModel.customerOrdersList[position] val newTotal = currentItem.itemTotal?.minus(1) // 对应扣减的删除数量 viewModel.customerOrdersList[position] = currentItem.copy(itemTotal = newTotal) // 3. 仅刷新当前item,不会影响其他商品 customerOrdersAdapter.notifyItemChanged(position) }
4. 可选适配多端同步场景
如果你的业务需要多端同步删除记录,必须保留全量删除表的观察者,可以在Observer回调时做新旧删除数据的差异比对,只更新有变动的对应商品,不要全量遍历刷新。
内容的提问来源于stack exchange,提问作者Block Person
相关产品推荐
相关产品推荐

