不断学习,做更好的自己!💪
视频号CSDN简书欢迎打开微信,关注我的视频号:KevinDev点我点我 LiveData官方文档:LiveData
首先,LiveData 和 ViewModel 的作用:ViewModel 和 LiveData 在整个 MVVM 架构中担当数据驱动的职责 官网定义:
LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. LiveData作用跟RxJava类似,是观察数据的类,相比RxJava,它能够在Activity、Fragment和Service之中正确的处理生命周期。
优点:
- 数据变更的时候更新UI
- 没有内存泄漏
- 不会因为停止Activity崩溃
- 无需手动处理生命周期
- 共享资源。
学习资料:
- 官方文档:ViewModel
- 谷歌实验室:教程
- 谷歌官方 Demo 地址:https://github.com/googlecodelabs/android-lifecycles
官网介绍: The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.
特点:
- 通常情况下,如果我们不做特殊处理,当屏幕旋转的时候,数据会消失;
- 同一个
Activity
的Fragment
之间可以使用ViewModel
实现共享数据。
1. 在 app/build.gradle 文件添加:
ext.lifecycleVersion = '2.2.0-alpha01'
dependencies {
...
// liveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.lifecycleVersion"
// viewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.lifecycleVersion"
}
2. 创建 ShoeModel
class ShoeModel constructor(shoeRepository: ShoeRepository) : ViewModel() {
// 品牌的观察对象 默认观察所有的品牌
private val brand = MutableLiveData().apply {
value = ALL
}
// 鞋子集合的观察类
val shoes: LiveData = brand.switchMap {
// Room数据库查询,只要知道返回的是LiveData即可
if (it == ALL) {
shoeRepository.getAllShoes()
} else {
shoeRepository.getShoesByBrand(it)
}
}
//... 不重要的函数省略
companion object {
private const val ALL = "所有"
}
}
3. 获取 ViewModel
-
方式一:无构造参数获取
ViewModelProviders.of(this).get(ShoeModel::class.java)
这样就可以返回一个我们需要的ShoeModel
了。 -
方式二:有构造参数获取
class ShoeModelFactory(
private val repository: ShoeRepository
) : ViewModelProvider.NewInstanceFactory() {
override fun create(modelClass: Class): T {
return ShoeModel(repository) as T
}
}
4. 使用 ViewModel
/**
* 鞋子集合的Fragment
*
*/
class ShoeFragment : Fragment() {
// by viewModels 需要依赖 "androidx.navigation:navigation-ui-ktx:$rootProject.navigationVersion"
private val viewModel: ShoeModel by viewModels {
CustomViewModelProvider.providerShoeModel(requireContext())
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding: FragmentShoeBinding = FragmentShoeBinding.inflate(inflater, container, false)
context ?: return binding.root
ViewModelProviders.of(this).get(ShoeModel::class.java)
// RecyclerView 的适配器 ShoeAdapter
val adapter = ShoeAdapter()
binding.recycler.adapter = adapter
onSubscribeUi(adapter)
return binding.root
}
/**
* 鞋子数据更新的通知
*/
private fun onSubscribeUi(adapter: ShoeAdapter) {
viewModel.shoes.observe(viewLifecycleOwner, Observer {
if (it != null) {
adapter.submitList(it)
}
})
}
}
5. 效果图