当前位置: 首页 > 知识库问答 >
问题:

希尔特-匕首视图模型从片段调用

孔鸿远
2023-03-14

我正在使用ViewModel更新动作栏中的标题

共享视图模型

class SharedViewModel @ViewModelInject constructor(
    @Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    val title: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }

    val backButton: MutableLiveData<Boolean> by lazy {
        MutableLiveData<Boolean>()
    }
}

主要活动观察者

@AndroidEntryPoint
...
sharedViewModel.title.observe(this, Observer {
    supportActionBar?.title = it
})

使用下面的代码似乎会在< code>Fragment中创建新的实例(在调试器中检查):

@AndroidEntryPoint
...
private val viewModel: SharedViewModel by viewModels()

但似乎是这样的

val viewModel = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)

文章参考

这是应该这样做还是我做错了什么?

谢谢你!

共有1个答案

袁俊弼
2023-03-14

如果您想要在片段中使用共享视图模型,您必须使用< code > by activityview models()而不是< code>by viewModels()。

为什么下一行有效,而 viewModels() 不起作用

ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)

因为默认情况下view Model s()ownerOUer参数值为{this}。为了更好地理解它,这里是源代码:

@MainThread
inline fun <reified VM : ViewModel> Fragment.viewModels(
    noinline ownerProducer: () -> ViewModelStoreOwner = { this },
    noinline factoryProducer: (() -> Factory)? = null
) = createViewModelLazy(VM::class, { ownerProducer().viewModelStore }, factoryProducer)

如您所见,它是Fra

但是,如果您按 activityViewModels() 使用,则使用 Activity 作为视图模型存储所有者。请注意使用 requireActivity().viewModelStore 而不是 ownerProducer().viewModelStore,后者默认是一个片段

@MainThread
inline fun <reified VM : ViewModel> Fragment.activityViewModels(
    noinline factoryProducer: (() -> Factory)? = null
) = createViewModelLazy(VM::class, { requireActivity().viewModelStore },
    factoryProducer ?: { requireActivity().defaultViewModelProviderFactory })

最终,< code>createViewModelLazy会调用

ViewModelProvider(store, factory).get(viewModelClass.java)

这相当于您使用手动创建视图模型

ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)

使用< code > by activityview models():

@AndroidEntryPoint
...
private val viewModel: SharedViewModel by activityViewModels()

注意:by activityViewModels() 和 by viewModels() 只是 ViewModelProvider(...) 的延迟加载实现。得到(...

 类似资料:
  • 我试图使用hilt将viewmodel注入片段,为此我创建了两个模块,一个用于我的网络组件,另一个用于角色的viewmodel。 网络模块安装在单例组件中,我需要将字符模块安装在FragmentComponent中,以通过“by view模型()”获取视图模型 我的活动和片段用“@AndroidEntryPoint”注释,我的应用程序用“@HiltAndroidApp”注释。我的模块是: 我的视图

  • 我正在使用Dagger-Hilt在我的Android项目中进行依赖注入,现在我遇到了这样的情况,我有一个基本的抽象片段 在这里,我有一个依赖项,即。我正在尝试做的是将注入到BaseViewModel中,以便在及其所有子项中可用。 < li >我尝试的第一种方法是使用构造函数注入,并将其注入到子节点,然后使用构造函数将其传递给超级节点。 这种方法工作得很好,但是我不需要将依赖关系从传递到类,我需要将

  • 这是一个自我回答的问题,我想在早些时候问这个问题,因为我的项目中存在代表曝光问题,但经过几个小时的研究,最终还是解决了这个问题。与其保持沉默,我想这可能会对将来的人有所帮助。本教程演示了如何创建Room数据库并在活动/片段中使用它。这里给出的示例用例是查询数据库的大小并更新片段中的视图。 注意:下面的代码中有一些 Dagger-Hilt 依赖项注入,但如果您手动执行自己的依赖项注入,则应应用相同的

  • 我正在写一个使用片段的简单示例。在主体活动中,有两个片段。第一个片段有一些文本视图,第二个片段有一些按钮。当用户点击textview时,文本打开按钮将被更改。 activity_main.xml mainactivity.java contentFrag.java 我没有编写控制按钮的操作,只是生成onclick事件。但是,我弄错了。请帮助我修复错误,并继续完成我的任务。

  • 当使用使用回调的第三方函数时,我试图返回指定的类型。我有一个接口 在实现接口时,我调用了一个使用回调的AWS Cognito异步函数。 在调用此方法时,如何仍返回身份验证结果的类型(注册在后台)?(我不想将其更改为 void,以便我可以在界面上使用匕首)。 编辑 我在dagger中尝试了许多不同的方法,但都不成功。我试图将下面的界面作为一个字段注入到一个活动中。 组件 然后我得到三个声明的错误,这

  • 问题内容: 我正在设计一个最适合我的用途,而不是使用成熟的PHP MVC。我已经完成了基本框架,并编写了运行网站所需的模型和控制器。 现在,我进入“视图”,遇到了一个小难题。我的方法对我来说很好,但是为了将来参考,我想知道我在做什么是否有不好的习惯。 我正在尝试做的是: 在我的视图中,我正在调用一个运行身份验证系统的模型,并请求用户的登录状态。然后,我使用该布尔值来决定是否在视图中显示某些元素,以