【问题标题】:Android ViewModel with Fragments causing the same data to be populated in different fragments带有片段的 Android ViewModel 导致相同的数据填充到不同的片段中
【发布时间】:2019-11-27 10:00:59
【问题描述】:

我最近在我的一个项目上切换到 Android MVVM,我面临的问题是,我的 Fragments 与 ViewPager 和 TabLayout 一起使用,每个选项卡的数据必须根据每个选项卡的 id 不同,但是因为我我正在使用 AndroidViewModel 连接到我的数据源,相同的数据显示在我的所有选项卡片段中。我知道问题是所有动态片段之间共享相同的 ViewModel [Fragmnet 类相同]。 有没有办法解决?或者我做错了什么。

//返回数据的代码

private MutableLiveData<List<InventoryProduct>> inventoryProductList;

//we will call this method to get the data
public LiveData<List<InventoryProduct>> getCategoriesList(String cat_id,String store_id) {
    //if the list is null
    if (inventoryProductList == null) {
        inventoryProductList = new MutableLiveData<>();
        //we will load it asynchronously from server in this method
        loadInventoryProducts(cat_id,store_id);
    }
    //finally we will return the list
    return inventoryProductList;
}

【问题讨论】:

  • 请给我们看代码
  • 对每个片段使用不同的视图模型
  • Fragment 类与基于参数创建的多个[动态] 实例相同。

标签: android android-fragments mvvm viewmodel android-viewmodel


【解决方案1】:

为多个片段使用相同的 ViewModel 并没有错,事实上,它在很多方面都有帮助。在您的情况下,我建议在片段中保留一些标识符,您可以将其传递给 ViewModel 的函数并相应地决定要提供哪些数据。这样不同的片段就会有不同的数据,只要 LifeCycleOwner 还活着,你的数据就会一直存在。 根据已编辑的问题,您将需要删除空检查,因为正在使用相同的 ViewModel 实例,一旦初始化,inventoryProductList 就不再为空,因此后续函数正在获取第一个片段的数据。作为一种解决方案(如果您不想采用 DB 方式),您可以像这样维护 LiveData 的 Map

Map<CatId/StoreId,LiveData<List<InventoryProduct>>> dataMap=new HashMap();

现在,您无需检查空值,而是检查您的 CatId/StoryID 的地图(基于您已经使用的密钥),如果地图还没有该值,则进行 API 调用,否则从地图。

类似的东西 假设您使用 StoreID 作为 Key

 if(!dataMap.containsKey(store_id)){
            MutableLiveData<List<InventoryProduct>> inventoryProductList = new MutableLiveData<>();
            //we will load it asynchronously from server in this method
            loadInventoryProducts(cat_id,store_id);
            dataMap.put(store_id,inventoryProductList);
//You need to post the response from the api call in this inventoryProductList

    }

    return dataMap.get(store_id);

确保在获得对应 cat_id/store_id 的 API 响应后,实际将数据发布到对应的 LiveData。

【讨论】:

  • 是的,我已经将标识符传递给片段并从那里传递给 ViewModel 的 loadData 方法,但仍然只有第一个数据通过 observable 被抛出到所有片段中。
  • 你能粘贴实际返回数据的代码吗?
  • 请检查,我已经用添加的代码更新了问题。
  • 谢谢。我想这可能会起作用,因为从逻辑上讲,这会将相应的数据返回到 Fragment。然而,我一直在寻找架构本身的任何解决方案。我想知道我是否做错了什么,但看起来我现在必须继续进行此修复。
  • 如果您尝试添加数据库并在这种情况下根据 cat_id 和 store_id 保存响应,您可以使用 Rooms LIveData 功能根据片段的要求订阅相应的 LiveData。如果您需要更多信息,请查看此处。 (codelabs.developers.google.com/codelabs/…)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多