如何实现Kotlin通用ViewModelProvider.Factory避免重复代码?
实现通用ViewModel工厂类GenericViewModelFactory
基础无参ViewModel实现
如果你的ViewModel都是无参构造的,这个基础版本的通用工厂类可以帮你避免重复编写多个工厂:
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider class GenericViewModelFactory(private val viewModelClass: Class<out ViewModel>) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { if (modelClass.isAssignableFrom(viewModelClass)) { @Suppress("UNCHECKED_CAST") return viewModelClass.newInstance() as T } throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}") } }
调用方式
在Fragment中直接传入对应ViewModel的Class对象即可:
- Fragment A:
val factory = GenericViewModelFactory(AViewModel::class.java) val viewModel = ViewModelProvider(this, factory)[AViewModel::class.java]
- Fragment B:
val factory = GenericViewModelFactory(BViewModel::class.java) val viewModel = ViewModelProvider(this, factory)[BViewModel::class.java]
扩展支持带参数的ViewModel
如果你的ViewModel需要构造参数(比如依赖Repository等),可以扩展通用工厂类来支持参数传递:
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider class GenericViewModelFactory<T : ViewModel>( private val viewModelClass: Class<T>, private vararg val constructorArgs: Any ) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { return try { // 获取匹配参数的构造函数 val paramTypes = constructorArgs.map { it.javaClass }.toTypedArray() val constructor = viewModelClass.getConstructor(*paramTypes) constructor.newInstance(*constructorArgs) as T } catch (e: Exception) { throw RuntimeException("Failed to create ViewModel instance", e) } } }
带参数调用示例
假设AViewModel需要传入UserRepository:
val userRepository = UserRepository() val factory = GenericViewModelFactory(AViewModel::class.java, userRepository) val viewModel = ViewModelProvider(this, factory)[AViewModel::class.java]
内容的提问来源于stack exchange,提问作者gee3107
相关产品推荐
相关产品推荐

