使用 Koin 和 navArgs 在子片段中获取共享视图模型



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

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
}

视图模型在 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)

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

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

在父片段中,绑定视图模型:

private val viewModel: UserDetailViewModel by viewModel()

之后,在您的子片段中包含在您的父片段的容器中:

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

此视图模型将使用父片段的视图模型存储,因此所有子片段的状态视图模型相同

Koin 版本 2.1.0

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

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

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

希望这能解决您的问题。

就我而言,我希望 viewpager2 中的 5 个片段在选项卡布局片段的单个 ViewModel 中相互通信。

以前我已经在 Koin 模块上将视图模型声明为 Singletone。Fragement第一次获得了合适的视图模型。但是,一旦我在导航后重新启动该片段,视图模型的行为就不合适了。

经过一些调试,我发现 viewmodelscope 不起作用,因为在我之前的视图销毁中清除了 vm,但由于单调模式,一旦我回到相同的片段,就会返回相同的实例。

通过搜索视图模型范围,我得到了这个问题跟踪器页面:

https://github.com/InsertKoinIO/koin/issues/506#issuecomment-521950186

所以,Koin无法在这种情况下使用当前版本。所以我在那之后尝试了这个解决方案..

我正在使用的视图模型需要一个存储库作为构造函数参数。我的Koin模块声明如下,

module {
factory { SearchApi() }
single<SearchRepo> { SearchRepoImpl(get()) } // It's dependant on SearchApi
}

我不是在Koin DI中声明视图模型。为了在所有片段中获取共享虚拟机,我使用了androidx.fragment委托:

val viewmodel by activityViewModels<SearchViewModel>()

但是为了使用存储库作为构造函数参数创建视图模型,我只使用了 Koin。

class SearchViewModelFactory : ViewModelProvider.NewInstanceFactory(), KoinComponent {
private val searchRepo: SearchRepo by inject()
override fun <T : ViewModel> create(modelClass: Class<T>): T = SearchViewModel(searchRepo) as T
}

并获取每个片段的共享虚拟机,

val searchViewModel: SearchViewModel by activityViewModels { SearchViewModelFactory() }

至少在Koin发布修复程序之前,这可能会帮助某人。 我目前的Koin-android版本:

2.1.5

使用的库:

implementation "org.koin:koin-android:$koin_version"
implementation "org.koin:koin-android-viewmodel:$koin_version"

这个代码实验室帮助获得了安卓工件,

https://developer.android.com/codelabs/basic-android-kotlin-training-shared-viewmodel#0

相关内容

  • 没有找到相关文章

最新更新