7

我有单个 Activity 应用程序。

我想将 viewModel 绑定到父片段生命周期 ( FlowFragmentLogin),并与子片段 ( CellFragment, InfoFragment, etc) 共享它。所以当我从FlowFragmentLoginto移动时FlowFragmentMain, viewModelonCleared()被调用。

但我发现的唯一方法是在 Activity 之间共享 viewModel,它是 Fragments: https ://insert-koin.io/docs/1.0/documentation/koin-android/index.html

并且无法控制生命周期所有者。这对我来说是不可接受的,至少因为这个 viewModel 将一直存在到应用程序死亡。

4

3 回答 3

4

由于导航2.1.0-alpha02

您现在可以通过 Kotlin 用户的 by navGraphViewModels() 属性委托或使用添加到 NavController 的 getViewModelStore() API 创建在导航图级别范围内的 ViewModel。

您可以在此处找到更改日志和文档

不幸的是,Koin 无法支持该功能,因为它viewModel()sharedViewModel()Activity 绑定在一起。但是对导航的支持已经计划好了,你可以在这里2.1.x跟踪。


现在这是我的解决方案:

  1. 在 Koin 中使用navGraphViewModels()而不是。viewModel()
class DetailFr : Fragment() {
    private val vm: DetailViewModel by navGraphViewModels(R.id.main_nav_graph)
}
  1. 使 ViwModel 实现KoinComponent,以便我们可以使用by inject()而不是通过构造函数注入。
class DetailViewModel : ViewModel(), KoinComponent {

    private val repo: DetailRepository by inject()
    // othetr objects you need
}

希望这会有所帮助

于 2019-07-15T03:10:38.913 回答
3

你可以通过使用新版本的Koin(2.1.0)和一些魔法来做到这一点:)

您只需要添加此扩展功能:

inline fun <reified VM : ViewModel> Fragment.sharedGraphViewModel(
    @IdRes navGraphId: Int,
    qualifier: Qualifier? = null,
    noinline parameters: ParametersDefinition? = null
) = lazy {
    val store = findNavController().getViewModelStoreOwner(navGraphId).viewModelStore
    getKoin().getViewModel(ViewModelParameter(VM::class, qualifier, parameters, null, store, null))
}

现在您可以通过以下方式从嵌套图中简单地获取 ViewModel:

private val viewModel: MyViewModel by sharedGraphViewModel(R.id.my_graph)
于 2020-02-25T09:53:24.330 回答
1

在 Koin 版本3.1.3中有一个新的扩展功能koinNavGraphViewModel

只需添加以下依赖项

implementation "io.insert-koin:koin-androidx-navigation:$koin_version"

可以这样使用

private val viewModel: MyViewModel by koinNavGraphViewModel(R.id.my_graph)

于 2021-12-13T12:05:38.547 回答