使用 Koin 和 navArgs 在 childfragment 中获取共享视图模型

Typ*_*aon 5 android viewmodel android-fragments koin

我有一个基本上只包含底部导航和视图模型的片段。该视图模型由该片段中的所有子片段共享。我的父片段看起来有点像这样:

class UserDetailFragment : Fragment() {

    private val args: UserDetailFragmentArgs by navArgs()
    private val userDetailViewModel: UserDetailViewModel by viewModel { parametersOf(args.user) }

    //standard code
    //onCreateActivity where I do some basic stuff like switching the fragments
}
Run Code Online (Sandbox Code Playgroud)

视图模型在 koin 中注册,如下所示:

val viewModelModule = module {
        /* other viewmodels */
        viewModel { (user: UserModel) -> UserDetailViewModel(get(), get(), user) }
    }

Run Code Online (Sandbox Code Playgroud)

然后我们有我试图这样定义的子片段:

class UserAlbumsFragment : Fragment() {

    private val userDetailViewModel: UserDetailViewModel by sharedViewModel() //THIS LINE ISN'T WORKING

    //standard code again
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的一行不起作用,我尝试将其写为:

private val userDetailViewModel: UserDetailViewModel 
   by sharedViewModel(from = { parentFragment as ViewModelStoreOwner })
Run Code Online (Sandbox Code Playgroud)

但我不断收到此错误:

Caused by: org.koin.core.error.NoParameterFoundException: Can't get parameter value #0 from org.koin.core.parameter.DefinitionParameters@426de94
        at org.koin.core.parameter.DefinitionParameters.elementAt(DefinitionParameters.kt:31)
        at org.koin.core.parameter.DefinitionParameters.component1(DefinitionParameters.kt:33)
        at com.kvw.technicaltestmediamonks.di.KoinModules$viewModelModule$1$5.invoke(Unknown Source:11)
        at com.kvw.technicaltestmediamonks.di.KoinModules$viewModelModule$1$5.invoke(KoinModules.kt:37)
        at org.koin.core.instance.DefinitionInstance.create(DefinitionInstance.kt:54)
Run Code Online (Sandbox Code Playgroud)

如何在不再次定义 userModel 的情况下获取此视图模型?

Kra*_*o13 6

如果您有一个带有容器和底部导航的片段,您可以尝试以下技巧:

在您的父片段中,您绑定 ViewModel:

private val viewModel: UserDetailViewModel by viewModel()
Run Code Online (Sandbox Code Playgroud)

然后在包含父片段容器的子片段中:

private val viewModel by lazy { requireParentFragment().getViewModel<UserDetailViewModel>() }
Run Code Online (Sandbox Code Playgroud)

该 ViewModel 将使用父片段的 viewModelStore,因此所有子片段的 viewModel 状态都相同

科因版本2.1.0


小智 4

我遇到了同样的问题,当我在 koin 中注册模块时,我通过将 viewModel 更改为 single 来解决这个问题。根据您的情况,尝试使用此代码进行修改

val viewModelModule = module {
    /* other viewmodels */
    single { (user: UserModel) -> UserDetailViewModel(get(), get(), user) }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用viewModel而不是single,Koin将在您调用sharedViewModel()时创建新对象。因此需要用户参数来重新创建视图模型。

希望这能解决您的问题。