使用Koin an navArgs获取子片段中的sharedviewmodel

时间:2019-11-28 17:58:29

标签: android android-fragments viewmodel 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
}

viewmodel像这样在koin中注册:

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

然后有我要定义的子片段:

class UserAlbumsFragment : Fragment() {

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

    //standard code again
}

如您所见,一行没有用,我尝试将其写为:

private val userDetailViewModel: UserDetailViewModel 
   by sharedViewModel(from = { parentFragment as ViewModelStoreOwner })

但我不断收到此错误:

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)

如何在不再次定义userModel的情况下获取此ViewModel?

2 个答案:

答案 0 :(得分:1)

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

在父片段中,绑定ViewModel:

private val viewModel: UserDetailViewModel by viewModel()

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

private val viewModel by lazy { requireParentFragment().getViewModel<UserDetailViewModel>() }

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

Koin版本2.1.0

答案 1 :(得分:0)

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

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

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

希望这可以解决您的问题。