Reset/clear 视图模型或实时数据

Reset/clear viewmodel or livedata

我正在遵循 Google 建议的 one-single-activity 应用程序模式,所以如果我想在 Fragments 之间共享数据] 我必须分享一个 ViewModel 其所有者必须是父 Activity所以,问题变成了因为我只想在两个片段之间共享数据,而与其他片段无关。

假设我有 MainFragmentCreateItemFragmentScanDetailFragment。因此,从第一个导航到 CreateItemFragment,每当我按下按钮时,我导航到 ScanDetailFragment 以扫描条形码,因此,通过 ViewModel 中的 LiveData 对象,我可以将扫描的值返回到ScandDetailFragment 完成后的 CreateItemFragment。当我决定取消项目的创建时,问题就出现了:我回到“MainFragment”,因为 ViewModel 的所有者是 Activity 的生命周期,一旦我再次进入 CreateItemFragment,之前扫描的值为还在。

有重置 ViewModel 的想法吗?

在这种情况下,您可以使用回调在片段之间共享数据。或者,如果您使用 DB/Sharedpreference/Content 提供程序,那么您不必担心共享数据,每个页面都会从商店中获取自己的数据 (DB/SharedPreference/Contentprovider)。

如果本指南对您有帮助,您也可以尝试https://medium.com/@lucasnrb/advanced-viewmodels-part-iii-share-a-viewmodel-between-fragments-59c014a3646

每次从MainFragment进入CreateItemFragment时都可以清除LiveData值。

或者您可以通过 onBackPressed() 方法中的 CreateItemFragment 清除它。

当你取消项目的创建时,在观察者代码中将 livedata 值设置为 null.then if(updatedvalue!=null) 使用更新的实时数据编写你的代码 value.in 这样你就可以避免最后更新值。

but, aren't Viewmodels also aimed to share data between different views?

没有。每个视图模型应该负责一个视图。 “共享视图模型”模式适用于您有一个大视图(即 activity)的情况,该视图具有多个需要共享数据/状态的子视图(即片段),例如 the master / detail example in the documentation。当您需要在子视图之间进行实时更新时,这对这些情况很方便。

在您的情况下,您在片段之间导航,因此应该通过转换传递数据。这意味着 passing arguments along when starting new fragments and registering for results when they complete their task.

那么你的每个片段都是孤立的、独立的、更容易测试的,你不会最终得到一个做所有事情™的上帝视图模型,并在你试图跳过时变成一团糟篮球占它可能处于的每个状态。

目前(2022 年),viewmodel.getViewModelStore.clear();onCleared(); 方法已弃用

因此,如果您想清除 ViewModel 持有的数据或清除 LiveData 的值,您只需使用 1 行代码,如下所示:

mainViewModel.getLiveData().getValue().clear();
  • getLiveData() 是我在 MainViewModel 中的方法 class 到 return liveData 变量
  • getValue() 是 LiveData 提供的默认方法 (MutableLiveData: setValue(), postValue())

如果您需要在用户按下 Fragment 中的后退按钮时清除数据,您可以像下面的代码一样将其放在 onViewCreated 方法 - LifecycleFragment 的方法中。

private void handleOnBackPressed() {
        requireActivity().getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) {
            @Override
            public void handleOnBackPressed() {
                Objects.requireNonNull(mainViewModel.getLiveData().getValue()).clear();
                requireActivity().finish();
            }
        });
    }

我在 Git 上的项目如果您想参考代码(它仍在更新): https://github.com/Nghien-Nghien/PokeAPI-Java/blob/master/app/src/main/java/com/example/pokemonapi/fragment/MainFragment.java