android - 在 Fragment 中获取相同的 ViewModel 实例,该实例在 Activity 中使用参数定义

标签 android kotlin viewmodel koin

所以,我正在使用 Koin 进行依赖注入(inject),这是我在 Activity 中所做的

class ModuleDetailActivity : AppCompatActivity() {

    private lateinit var moduleId:String
    private lateinit var levelModule:Level.Module

    private val moduleViewModel: ModuleViewModel by viewModel { parameterOf(moduleId, levelModule) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        ...
        ...

        moduleId = intent.getString("module_id")
        levelModule = intent.getParcelable("level_module")

        ...
        ...
    }
}

现在,我有多个 ModuleDetailActivity 可以添加或替换的 fragment ,我想在这些 fragment 中使用相同的 moduleViewModel 实例,而不在 Fragment< 中传递任何参数.

class ModuleDetailFragment : Fragment() {

    private val moduleViewModel: ModuleViewModel by sharedViewModel()

    ...
    ...
}

我知道这会引发错误,正如预期的那样,您会看到这一点

Caused by: org.koin.core.error.InstanceCreationException: Could not create instance for [Factory:'****.ui.module.ModuleViewModel']

这是我初始化模块的方式

val viewModelModule = module {
    viewModel { (id : String, levelModule:Level.Module) -> ModuleViewModel(id, levelModule, get()) }
}

关于如何在 Activity 中定义相同的 ModuleViewModel 实例而不在 Fragment 中传递参数,是否有任何解决方案?

最佳答案

使用KOIN

ViewModel 实例可以在 Fragment 及其宿主 Activity 之间共享。

要在 Fragment 中注入(inject)一个共享的 ViewModel,请使用:

by sharedViewModel() - lazy delegate property to inject shared ViewModel instance into a property
getSharedViewModel() - directly get the shared ViewModel instance

只需声明 ViewModel 一次:

val weatherAppModule = module {

   // WeatherViewModel declaration for Weather View components
   viewModel { WeatherViewModel(get(), get()) }

}

在您的 Activity 中:

class WeatherActivity : AppCompatActivity() {

    /*
     * Declare WeatherViewModel with Koin and allow constructor dependency injection
     */
    private val weatherViewModel by viewModel<WeatherViewModel>()
}

在你的 fragment 中:

class WeatherHeaderFragment : Fragment() {

    /*
     * Declare shared WeatherViewModel with WeatherActivity
     */
    private val weatherViewModel by sharedViewModel<WeatherViewModel>()
}

其他 fragment :

class WeatherListFragment : Fragment() {

    /*
     * Declare shared WeatherViewModel with WeatherActivity
     */
    private val weatherViewModel by sharedViewModel<WeatherViewModel>()
}

关于android - 在 Fragment 中获取相同的 ViewModel 实例,该实例在 Activity 中使用参数定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60223209/

相关文章:

android - 如何运行具有不同首选项的Android Studio的两个实例,例如不同的SDK位置,不同的Gradle版本

javascript - 我如何在没有标准库的情况下使用 KotlinJS?

android - 搜索 Recyclerview - 当搜索为空时滚动到顶部

c# - 无法从父 View 模型WPF MVVM应用程序的弹出窗口中获取值

mvvm - 如何使用MVVM模式在ViewModel中的View中调用函数(与UIElements一起使用)

android - Chain animator设置android动画

Android - 如何获取 AudioManager/AudioSystem 参数列表

javascript - Nativescript 应用程序无法在 WebView 上打开文件选择器

android - 通过撰写导航传递 Parcelable 参数

kotlin - 如何使用Gradle Kotlin DSL向所有 jar 添加前缀