如何在 Kotlin 中编写扩展函数来实例化 AndroidViewModel?

Hel*_*oCW 5 android kotlin android-jetpack

有人写了两个扩展函数(代码A2)FragmentFragmentActivity实例化a ViewModel,效果很好,你可以看到代码A1和代码A3。

我希望为两者编写两个扩展函数(代码B2)FragmentFragmentActivity实例化一个AndroidViewModel,你可以看到代码B1和代码B3,我该怎么办?谢谢!

代码 A1

class HomeViewModel_A(private val mDBVoiceRepository: DBVoiceRepository) :  ViewModel() {

}
Run Code Online (Sandbox Code Playgroud)

代码 A2

inline fun <reified T : ViewModel> Fragment.getViewModel(noinline creator: (() -> T)? = null): T {
    return if (creator == null)
        ViewModelProvider(this).get(T::class.java)
    else
        ViewModelProvider(this, BaseViewModelFactory(creator)).get(T::class.java)
}

inline fun <reified T : ViewModel> FragmentActivity.getViewModel(noinline creator: (() -> T)? = null): T {
    return if (creator == null)
        ViewModelProvider(this).get(T::class.java)
    else
        ViewModelProvider(this, BaseViewModelFactory(creator)).get(T::class.java)
}
Run Code Online (Sandbox Code Playgroud)

代码 A3

class FragmentHome : Fragment() {
    private val mHomeViewModel_A by lazy {
        getViewModel {
            HomeViewModel_A(provideRepository(mContext))
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

代码 B1

class HomeViewModel_B(application: Application,private val mDBVoiceRepository: DBVoiceRepository) :  AndroidViewModel(application)  {

}
Run Code Online (Sandbox Code Playgroud)

代码 B2

?
Run Code Online (Sandbox Code Playgroud)

代码 B3

class FragmentHome : Fragment() {
  private val mHomeViewModel_B by lazy {     
       ?      
  }
}
Run Code Online (Sandbox Code Playgroud)

Ten*_*r04 5

Ktx Fragments 库已经有一个函数可以简洁地创建一个惰性委托来检索视图模型:Fragment.viewModels()FragmentActivity.viewModels()

这些适用于具有默认构造函数(分别为空或 Application 参数)的 ViewModel 和 AndroidViewModel,或者您可以使用尾随 lambda 返回一个视图模型工厂。你会像这样使用它:

class FragmentHome : Fragment() {
  private val mHomeViewModel_B: MyViewModel by viewModels()
}
Run Code Online (Sandbox Code Playgroud)

或者

class FragmentHome : Fragment() {
  private val mHomeViewModel_B: MyViewModel by viewModels { getMyViewModelFactory() }
}
Run Code Online (Sandbox Code Playgroud)

要获得与A2 中相同的东西,您可以包装此函数以让它为您构建一个工厂:

@Suppress("UNCHECKED_CAST")
inline fun <reified VM : ViewModel> Fragment.viewModelFactory(crossinline creator: () -> VM): Lazy<VM> {
    return viewModels {
        object : ViewModelProvider.Factory {
            override fun <T : ViewModel?> create(modelClass: Class<T>): T {
                return creator() as T
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)