Android 存储库模式 - 如何从视图模型更新嵌套的回收器视图项

Android Repository pattern - how to update a nested recycler view item from view model

我正在使用 ViewModel 和存储库模式来获取列表中的数据。这些项目排列为行和产品的列表。行 class 中有产品。产品可以水平滚动。我正在使用嵌套在另一个回收器视图(垂直方向)中的线性布局管理器(水平方向)的回收器视图。通过 ViewModel 获取项目并在回收器视图中呈现非常简单。挑战在于,当我将商品添加到购物车时尝试更新商品(它们的数量)。单击按钮(加号)时,回调将通过侦听器发送到视图模型。水平适配器将请求发送回容器(垂直)适配器,垂直适配器将请求发送回视图模型。

// The horizontal adapter
class SimpleProductAdapter(
    private val shopId: String,
    private val listener: (product: CartProduct) -> Unit
) :
    ListAdapter<CartProduct, RecyclerView.ViewHolder>(...DiffCallbackGoesHere) {

    // ... some more things here
    fun bind(item: CartProduct?) {
        view.add_to_cart_button.setOnClickListener {
            listener(item)
        }
    }

垂直适配器结构相似

class RowAdapter(
    private val shopId: String,
    private val listener: (product: CartProduct) -> Unit
) :
    PagedListAdapter<Row, RecyclerView.ViewHolder>(...RowDiffCallbackGoesHere) {
    
    // ... some more things here
    fun bind(item: Row?) {
        SimpleProductAdapter(shopId) { product ->
            listener(product)
        }
    }

片段中存在视图模型调用的主要站点:

val rowAdapter = RowAdapter(args.shopId) { product->
if (actionType == ADD_TO_CART_ACTION) viewModel.buy(product)
    .observe(viewLifecycleOwner, Observer {
        view.swipe.isRefreshing = it is Resource.Loading
        // I want to update the quantity here on success result
        if(Resource is Success) {}
    })

当结果为Success时,我想更新数量;这里有两件事具有挑战性

  1. 我正在使用分页库中的 PagedListAdapter,它为我提供了一个(假设)不可变的产品列表。
  2. 即使我更新了 PagedList 并发出了 notifyDataSetChanged,仅仅更改大量项目的单个计数也太过分了。

我希望找到一种方法,让我可以轻松地针对特定产品进行更新,或者我一直在网上看到的另一种选择是 构建自定义布局管理器 所以我可以有一个单一的适配器,在一次传递中绘制所有内容,而无需嵌套回收器视图。这样更新项目会变得更容易(找不到关于此的代码示例)。

有什么建议吗

在 Paging3 中,有计划最终添加一个 API 来支持粒度更新而不失效:https://issuetracker.google.com/160232968

目前,您必须使数据失效才能更新后备数据集。不过,一般来说,DiffUtil 可以很好地向用户隐藏这一点。