- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Google 通过将 SharedViewModel 限定在 Activity 范围内声明在 Fragment 之间进行通信时使用 SharedViewModel。
在单个 Activity 应用程序中,这意味着 Activity 将散布着可能不再需要的 ViewModel,它们将在整个生命周期内保留在那里。考虑一些示例,例如扩展的注册流程或考虑几个屏幕的内容。
推荐的一种方法是使用父 fragment 作为范围,但这只有在有父 fragment 的情况下才有可能。它可以只是不同的 fragment 。
我想出了以下解决方案,我想知道它的可行性如何或有多糟糕,是否有更好的解决方案?
为了简单起见,考虑到我有两个名为 ExampleOneFragment
和 ExampleTwoFragment
的 Fragment,我希望它们有一个共享范围,而不是实际将其范围限定到 Activity。假设我想从 ExampleTwoFragment
更新 ExampleOneFragment
中的 TextView ,所以我为两者创建了一个这样的 SharedViewModel
对于 ExampleOneFragment
它将是:
private val mSharedViewModel by lazy {
ViewModelProvider(this).get(SharedViewModel::class.java)
}
对于ExampleTwoFragment
,我想到了这个:
private val mSharedViewModel by lazy {
ViewModelProvider(supportFragmentManager().findFragmentByTag(ExampleOneFragment.TAG) ?: this).get(SharedViewModel::class.java)
}
这似乎可行,但我不知道这会导致什么样的问题。
我发现的其他一些解决方案是:根据@mikhehc here我们实际上可以创建自己的 ViewModelStore。这将使我们能够精细地控制 ViewModel 必须存在的范围。但我不明白如何让它适用于 Fragments?
其次,仍然是将其范围限定到 Activity 的 hacky 方法,但使用与 I found here 相同的键通过虚拟 View 模型将其清除
谁能指导我什么是正确的方法?我不能转移到 NavGraphs,因为它是一个已经启动并正在运行的项目,而且 Activity 的范围感觉不对。谢谢。
最佳答案
This seems to be working, but I don't know what kind of issues can this cause.
此代码仅在以下情况下有效:
ExampleOneFragment
ExampleOneFragment.TAG
标签添加到 ExampleTwoFragment
使用的同一个 FragmentManager
如果这些假设中的任何一个失败,您将得到单独的 View 模型实例,因为 supportFragmentManager().findFragmentByTag(ExampleOneFragment.TAG) ?: this
将解析为 this
.
But I don't understand how to make it work for Fragments?
您可以按照该答案中显示的方式使用它,或者通过接受 ViewModelStoreOwner
的任何其他方式使用它。在这一行中:
val viewModel = ViewModelProvider(myApp, viewModelFactory).get(CustomViewModel::class.java)
您将从您的 Fragment
中获取 myApp
作为:
val myApp = requireContext().application as MyApp
就我个人而言,我认为您指出的解决方案风险很大。 ViewModelStore
在进程的整个生命周期内都存在,永远不会被清除。您最终会在所有内容上共享您的 View 模型,并且该 View 模型所做的所有内容都会泄露。创建自定义 ViewModelStoreOwner
的概念很好,但您应该做一些事情将该所有者的范围与其存储的 View 模型的相关生命周期联系起来。答案试图在最后一段中绕过它;太多的开发人员会忽略这一点并遇到问题。
One way recommended was using a parent Fragment as scope, but that is only possible if there is a parent fragment. It can be just different Fragments.
那么,您的应用并未以“开箱即用”的方式编写自动 ViewModelStoreOwner
管理。
最后,您正在寻找要在这两个 fragment 之间共享的 ViewModelStoreOwner
。在您的第一个解决方案中,您试图通过使用其中一个 fragment 中的 ViewModelStoreOwner
来破解它,这只有在您可以可靠地选择哪个 fragment 时才有效。在您在另一个答案中指出的解决方案中,您正试图通过故意泄漏 ViewModelStoreOwner
来破解它。
您可能还可以考虑其他方法,具体取决于您的情况。例如,您的依赖倒置框架(Dagger/Hilt、Koin 等)可能有一些选项可以装配一个 ViewModelStoreOwner
绑定(bind)到特定的 fragment 实例对。
关于android - 如何在一组特定 fragment 之间共享 ViewModel 范围,而不使用 NavGraphs 或将其范围限定到 Activity ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67544852/
在我的 Activity 布局中,我有以下 NavHostFragment: 我的问题是如何以编程方式设置 navGraph?如何在 NavHostFragment 实例中转换 my_nav_hos
我有一个带有主要 Activity 的简单应用程序,一个 fragment frag_home ,以及一个名为 ItemFragment 的列表 fragment . 在 frag_home我有一个日
我开始学习共享 View 模型。 目前我在 Activity 中有 3 个 fragment ,其中 2 个在嵌套的 navGraph 中。 我想为它们创建共享的 navGraph viewModel
我有一个看起来像这样的 NavGraph: @Composable fun NavGraph ( navController: NavHostController ) { NavHos
我有 3 个项目的底部导航 View ,我的 navGraph看起来像这样: 带有嵌套 navGraph fragment 的底部导航 View 中的导航正常工作,但如果我
我正在尝试为我的订单管理应用程序构建以下导航: manage_orders/manage_orders/{locationId} manage_orders/manage_order_details/
我知道用 XML 构建 NavGraph 很容易,但是如何用 java 代码实现呢? 没有“app:navGraph”属性的 fragment XML 定义: TestActivity.java
我想在许多可组合项之间共享一个 View 模型。就像我们如何在 Activity 中的 fragment 之间共享 View 模型一样。 但是当我尝试这个 setContent { val n
我知道关于这个问题有几个问题和答案,但没有一个解决方案能解决我的问题。我得到一个 android.view.InflateException: Binary XML file line #11: Bi
在升级到最新的 fragment (1.2.2 版本)和导航(2.2.1 版本)后,为了防止出现 Lint 警告(将 fragment 替换为 FragmentContainerView),我将 fr
从 更新导航组合依赖后2.4.0-alpha03 至 2.4.0-alpha05 在尝试在可组合屏幕之间导航(例如从 taskComposable 导航到 listComposable 屏幕)后,我遇
在我的应用程序中,我使用具有多个片段架构的单个 Activity ,并使用导航库在它们之间导航。在其中一个片段中,我有多个类别,每个类别都与一个 ID 相关联。当点击一个类别时,我会使用下面的代码将用
Google 通过将 SharedViewModel 限定在 Activity 范围内声明在 Fragment 之间进行通信时使用 SharedViewModel。 在单个 Activity 应用程序
我正在使用 刀柄 对于 依赖注入(inject) 专门用于注入(inject)查看型号 . 还想范围 ViewModel 到 NavGraph .为此,请获取 ViewModelStoreOwner
我创建了一个 Android 应用程序,并从 Gallery 添加了“Navigation Drawer Activity”,我删除并重命名了菜单项。当我单击抽屉 Activity 中的任何菜单项启动
考虑这个例子。 对于身份验证,我们将使用 2 个屏幕 - 一个屏幕输入电话号码,另一个屏幕输入 OTP。 这两个屏幕都是在 Jetpack Compose 中制作的,对于 NavGraph,我们使用的
我试图在我的应用程序中实现导航功能。当我尝试构建应用程序时,输出显示: Android resource linking failed /home/mateusz/AndroidStudioProje
我是一名优秀的程序员,十分优秀!