ViewModel 是jetpack(Google 提供的应用开发框架)中的解耦数据和UI,可感知生命周期的方式存储数据,可以随着Activity的生命周期进行数据的控制,解决了以前Activity的切换横竖屏重新加载数据等问题,但是ViewModel 最主要的不是保存短在的数据在其属性中,而是通过它进行数据与UI的无感知更新,
ViewModel 存在的时间范围是获取ViewModel 时传递给ViewModelProvider的Lifecycle,而后ViewModel一直会留存在内存中,直到存在时间范围的Lifecycle永久消失,
上图对应了到Activity发生屏幕旋转而结束生命周期的过程中所处的各种状态,
class PictureViewModel : ViewModel(){
val pictureView: MutableLiveData<List<String>> = MutableLiveData()
}
class PictureFragment : Fragment() {
// 1. 申明ViewModel
private lateinit var viewModel: PictureViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_picture, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// 2. 初始化
viewModel = ViewModelProviders.of(this).get(PictureViewModel::class.java)
// 3.使用
viewModel.pictureView.observe(viewLifecycleOwner, Observer {
})
}
}
使用其实分上述三步:
这个是基本是官方提供的使用方式。但是我们需要给我们的ViewModel 传递一个参数,我们怎么做?
其实上面那个问题官方提供了ViewModelProvider.Factory来解决,我今天就是要通过ViewModelProvider.Factory来集中式的使用ViewModel
涉及类:
已经描述的很清楚了,看一下具体实现
根据依赖关系,可以倒先写PictureRepository,在写ViewModel,接着PictureViewModelFactory,哈哈无所谓啊
// 数据来源
class PictureRepository private constructor(private val context: Context) {
fun getData() :MutableLiveData<List<String>>{
// 返回珍视数据
return MutableLiveData()
}
companion object {
@Volatile
private var instance: PictureRepository? = null
fun getInstance(context: Context) = instance ?: synchronized(this) {
instance ?: PictureRepository(context).also { instance = it }
}
}
}
// ViewModewl 传入PictureRepository,调用获取数据方法
class PictureViewModel internal constructor(repository: PictureRepository) : ViewModel(){
val pictureView: MutableLiveData<List<String>> = repository.getData()
}
@Suppress("UNCHECKED_CAST")
class PictureViewModelFactory(private val repository: PictureRepository): ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
// 传入PictureRepository
return PictureViewModel(repository) as T
}
}
object InjectorUtils {
//提供给Activity/Fragment
fun providerPictureViewModelFactory(context: Fragment) :PictureViewModelFactory {
return PictureViewModelFactory(getPictureRepository(context.requireContext()))
}
private fun getPictureRepository(context: Context): PictureRepository {
return PictureRepository.getInstance(context.applicationContext)
}
}
在Fragment中使用:
class PictureFragment : Fragment() {
// private lateinit var viewModel: PictureViewModel
// 使用
private val viewModel: PictureViewModel by viewModels {
InjectorUtils.providerPictureViewModelFactory(this)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_picture, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// viewModel = ViewModelProviders.of(this).get(PictureViewModel::class.java)
viewModel.pictureView.observe(viewLifecycleOwner, Observer {
})
}
}
是不是方便很多,
代码