将数据从一个视图模型传递到另一个Android MVVM

时间:2019-10-26 17:19:46

标签: android mvvm android-jetpack android-jetpack-navigation android-architecture

我有一个与设计有关的问题。

因此,我一直遵循Google的Guide to App Architecture,使用Kotlin,MVVM和数据绑定来构建我的应用程序。我正在使用Google规定的Jetpack组件(导航,实时数据等)。

问题在于,在开发过程中,很多时候我需要将数据从一个片段传输到另一个片段。之前,我曾经创建片段的实例并添加复杂数据,然后移至片段,如下所示:

class Frag1: Fragment(){

    ...
    fun openFrag2(){
        val frg2 = frag2.newInstance(complexDataObj)
        childFragmentManager.addFragment(frg2,TAG)
    }
}

class Frag2: Fragment(){
    var cd: ComplexDataClass = null
    companion object{
    fun newInstance(complexData: ComplexDataClass): Fragment{
        val frag = ActivityFragment()
        frag.cd = complexData
        return frag
    }
    ....
}

使用navigation在目标之间传递数据应该像this或使用 Shared View Model ,这在同一文档中也有提及。 >>

  

通常,您强烈建议在目标之间仅传递最少量的数据。例如,您应该传递键来检索对象而不是传递对象本身,因为所有保存状态的总空间在Android上受到限制。如果您需要传递大量数据,请考虑使用“在片段之间共享数据”中所述的ViewModel。

这有效。

我的问题是,使用体系结构的主要原因之一是关注点分离。这样我们就可以编写干净且可维护的代码。根据我的理解,sharedviewmodel的这种用法无法达到目的,因为这会导致大型ViewModel类。

我将尝试用非常普遍的情况来解释问题。

我有一个包含数据列表的片段。列表中的每个项目都对应一个用户。点击项目时,它应移至用户详细信息屏幕,如果点击编辑按钮,则应移至可编辑详细信息的编辑屏幕。

             View User Frag
             ____                 ____________
            |    |               |            |
 List Frag  |    |               |            |
 ______     |____|               |            |
|______| /
|______|/                        |            |
|______|\                        |            | Huge Shared ViewModel class
|______| \
            Edit User Frag       |            |
            _____
           |     |               |            |
           |     |
           |_____|               |____________|

因此,在这种情况下,由于需要从列表类向视图和编辑片段发送用户数据,因此将在这三个片段之间共享ViewModel,并且共享的ViewModel将具有所有三个片段的业务逻辑。

所以这似乎不适合我,因为ViewModel太复杂了,无法在许多情况下像这样共享:

model = activity?.run {
        ViewModelProviders.of(this)[SharedViewModel::class.java]
    } ?: throw Exception("Invalid Activity")

将给出相同的视图模型实例。

我需要知道我对这个sharedviewmodel的理解是否错误,如果是这样,请纠正我。如果我的理解正确,请让我知道在这种情况下如何更有效地管理视图模型。

1 个答案:

答案 0 :(得分:1)

ViewModel中可以有多个Fragment,因此无需与3个较小的逻辑中的所有逻辑保持巨大的共享ViewModel

您可以创建一个额外的共享ViewModel,该共享仅关心实际的公共数据,并将3个单独的特定于片段的ViewModel分开。

sharedModel = activity?.run {
        ViewModelProviders.of(this)[SharedViewModel::class.java]
    } ?: throw Exception("Invalid Activity")
localViewModel = ViewModelProviders.of(this).get(LocalViewModel::class.java)