Android Fragments 重置/清除视图模型或实时数据

gr8qqesn  于 2023-01-13  发布在  Android
关注(0)|答案(6)|浏览(294)

我遵循Google建议的 one-single-activity 应用模式,因此如果我想在Fragments之间共享数据,我必须共享一个所有者必须是父ActivityViewModel因此,问题变成了因为我只想在两个Fragment之间共享数据,而与其他Fragment无关。
假设我有MainFragmentCreateItemFragmentScanDetailFragment,那么,从第一个开始,我导航到CreateItemFragment,每当我按下按钮时,我导航到ScanDetailFragment,以便扫描条形码,因此,通过ViewModel内的LiveData对象,我可以在ScandDetailFragment完成后将扫描值返回CreateItemFragment。当我决定取消项目的创建时,问题变成了:我回到'MainFragment',因为ViewModel的所有者是Activity的生命周期,所以当我再次进入CreateItemFragment时,之前扫描的值仍然存在。

是否有重置该ViewModel的想法?

zi8p0yeb

zi8p0yeb1#

但是,Viewmodels不也是为了在不同视图之间共享数据吗?
不。每个视图模型应该负责一个视图。“shared viewmodel”模式适用于一个大视图(即Activity)包含多个需要共享数据/状态的子视图(即片段)的情况,就像文档中的主视图/细节视图示例。当您需要子视图之间的实时更新时,它非常方便。
在您的例子中,您在片段之间“导航”,因此应该通过转换“传递数据”,这意味着passing arguments along when starting new fragments并在它们完成任务时注册结果。
这样,你的每一个片段都是孤立的、自包含的、更容易测试的,你就不会最终得到一个做所有事情的上帝观模型,而当你试图跳过铁环来解释它可能处于的每一种状态时,它就变成了一个巨大的混乱。

zd287kbt

zd287kbt2#

在这种情况下,您可以使用回调在片段之间共享数据。或者,如果您使用DB/Sharedpreference/Content provider,则不必担心共享数据,每个页面都将从存储(DB/SharedPreference/Contentprovider)中获取自己的数据。
如果本指南有帮助,您也可以尝试https://medium.com/@lucasnrb/advanced-viewmodels-part-iii-share-a-viewmodel-between-fragments-59c014a3646

u0njafvf

u0njafvf3#

每次从MainFragment进入CreateItemFragment时,可以清除LiveData值。
或者您可以直接从CreateItemFragment in onBackPressed()方法中清除它。

wyyhbhjk

wyyhbhjk4#

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

rwqw0loc

rwqw0loc5#

目前(2022年),方法viewmodel.getViewModelStore.clear();onCleared();已被弃用
所以,如果你想清除ViewModel持有的数据或清除LiveData的值,你只需要使用1行代码如下:

mainViewModel.getLiveData().getValue().clear();
  • getLiveData()是我在MainViewModel类中用于返回liveData变量的方法
  • getValue()是LiveData提供的默认方法(可变LiveData:设置值(),后值())

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

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

s5a0g9ez6#

我不同意@dominicoder。在这个链接上,你可以找到一个由谷歌团队制作的Codelab,更新到2021年10月30日。当你需要一个连贯的流程来完成应用中的特定任务时,可以使用共享的ViewModel模式。
这种方法很有用,是一种良好的做法,因为:

  • Jetpack团队说,这从来都不是通过Parcelables的推荐模式,因为我们希望有一个单一的真实来源。
  • 到目前为止,多个活动(to see more)已经被严重禁止了好几年,所以即使你没有使用Jetpack compose,你仍然应该使用一个共享的ViewModel沿着片段来保持单一的真实来源。

缺点:

  • 你需要手动重置所有数据。忘记这样做会给你的应用带来bug,而且大多数时候,这些bug很难被发现。

相关问题