LiveData
1、定义:可观察的数据持有对象
2、优点:
(1)自动更新UI
(2)无内存泄漏
(3)不会引起程序崩溃
(4)无需手动处理生命周期
(5)共享资源 -- 需要继承LiveData并且实现单例
ViewModel
1、定义:用来处理跟UI相关的数据的类
2、优点:
(1)设备信息发生变更数据不会消失
(2)同一个Activity之间的Fragment可以实现数据共享 -- 使用Fragment中的activity提供ViewModel
1、添加依赖
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、简单实现
【1】创建ViewModel,并在ViewModel创建MutableLiveData
class UserModel(application: Application) : AndroidViewModel(application) {
val userLiveData = MutableLiveData<User>() // 创建 LiveData 对象
private var mApplication: Application? = null
init {
userLiveData.postValue(User("张三", 2)) // 通知数据变化了
mApplication = application
}
/**
* 更新用户信息
*/
fun updateUserInfo() {
val user = userLiveData.value?.apply {
userName = "张三"
age = (1..100).random()
}
userLiveData.value = user // 或改成 userLiveData.postValue(user)
}
}
【2】User类
data class User(var userName: String, var age: Int)
【3】ViewModelProvider
val userModel = ViewModelProvider(this@LiveDataActivity).get(UserModel::class.java)
【4】使用 observe 或 observeForever 绑定观察者
// 使用 observe 会让观察者随着生命周期的活跃而活跃,当生命周期处于活跃状态时LiveData才会更新数据,反之不会更新数据
// 不需要主动调用 removeObserver(Observer) 移除观察者
userModel.userLiveData.observe(this@LiveDataActivity, Observer<User> {
binding.userinfo.text = "大家好,我叫" + it.userName + ",今年" + it.age + "岁了!"
})
// 使用 observeForever,会导致观察者一直处于活跃状态
// 我们需要主动调用 removeObserver(Observer) 移除观察者
userModel.userLiveData.observeForever {
binding.userinfo.text = "大家好,我叫" + it.userName + ",今年" + it.age + "岁了!"
}
【5】触发数据变化
binding.activityDataButton.setOnClickListener {
userModel.updateUserInfo()
}
3、map 和 switchMap
// 使用map函数,将User类型转成Int类型,Observer的返回值也从User类型转换成Int类型
// Function 第一个参数表示输入,第二个参数表示输出
// map 第一个参数表示输入数据,第二个参数Function的返回值是输出数据
Transformations.map(userModel.userLiveData, Function<User, Int> {
it.age
}).observe(this@LiveDataActivity, Observer<Int> {
binding.userinfo1.text = "大家好,我今年 $it 岁了!"
})
// 使用switchMap函数,将User类型转成LiveData<Int>类型,Observer的返回值从User类型转换成Int类型
// Function 第一个参数表示输入,第二个参数表示输出
// map 第一个参数表示输入数据,第二个参数Function的返回值是输出数据
Transformations.switchMap(userModel.userLiveData, Function<User, LiveData<Int>> {
val userLiveData = MutableLiveData<Int>()
val age = userModel.userLiveData.value?.age
userLiveData.postValue(age)
userLiveData
}).observe(this@LiveDataActivity, Observer<Int> {
binding.userinfo.text = "大家好,我今年 $it 岁了!"
})
其它步骤和 【2】 保持一致。
4、使用 MediatorLiveData 统一管理多个LiveData
【1】创建ViewModel,并在ViewModel创建MediatorLiveData和MutableLiveData
class UserModelByMediator(application: Application) : AndroidViewModel(application) {
var mediatorLiveData: MediatorLiveData<User> = MediatorLiveData() // 创建 LiveData 集合对象,管理多个LiveData
val userLiveData1 = MutableLiveData<User>() // 创建 LiveData 对象1
val userLiveData2 = MutableLiveData<User>() // 创建 LiveData 对象2
private var mApplication: Application? = null
init {
mediatorLiveData.addSource(userLiveData1) {
mediatorLiveData.value = it
}
mediatorLiveData.addSource(userLiveData2) {
mediatorLiveData.value = it
}
userLiveData1.postValue(User("张三", 2)) // 通知数据变化了
userLiveData2.postValue(User("李四", 3)) // 通知数据变化了
mApplication = application
}
/**
* 更新用户信息1
*/
fun updateUserInfo1() {
val user = userLiveData1.value?.apply {
userName = "张三"
age = (1..100).random()
}
userLiveData1.value = user // 或改成 userLiveData1.postValue(user)
}
/**
* 更新用户信息1
*/
fun updateUserInfo2() {
val user = userLiveData2.value?.apply {
userName = "李四"
age = (1..100).random()
}
userLiveData2.value = user // 或改成 userLiveData2.postValue(user)
}
}
【2】user类
和上面一致
【3】ViewModelProvider
val userModelByMediator = ViewModelProvider(this@LiveDataActivity).get(UserModelByMediator::class.java)
【4】绑定观察者
userModelByMediator.mediatorLiveData.observe(this@LiveDataActivity) {
when(it.userName) {
"张三" -> binding.userinfo1.text = "大家好,我叫${it.userName},今年${it.age}岁了!"
"李四" -> binding.userinfo2.text = "大家好,我叫${it.userName},今年${it.age}岁了!"
}
}
【5】触发数据变化
binding.activityDataButton.setOnClickListener {
userModelByMediator.updateUserInfo1()
userModelByMediator.updateUserInfo2()
}
5、LiveData的单例实现
【1】创建一个单例
class UserLiveData : LiveData<User>() {
companion object {
private lateinit var mInstance: UserLiveData
@JvmStatic
@MainThread
fun get(): UserLiveData {
mInstance = if (::mInstance.isInitialized) {
mInstance
} else {
UserLiveData()
}
return mInstance
}
}
override fun onActive() {
super.onActive()
}
override fun onInactive() {
super.onInactive()
}
/**
* 更新数据
*/
fun updateUserInfo() {
var user = get().value
if (user == null) {
user = User("", 0)
}
user.apply {
userName = "张三"
age = (1..100).random()
}
value = user // 或者 将 value = user 改成 postValue(user)
}
}
onActive 和 onInactive 两个方法很重要
onActive:Activity 激活时执行
onInactive:Activity 挂起时执行
【2】绑定观察者
// LiveData单例实现方式
UserLiveData.get().observe(this@LiveDataActivity) {
binding.userinfo1.text = "大家好,我叫" + it.userName + ",今年" + it.age + "岁了!"
}
【3】触发数据更新
binding.activityDataButton.setOnClickListener {
UserLiveData.get().updateUserInfo()
}
6、ViewModelProvider.Factory使用
没有使用 ViewModelProvider.Factory 的代码:
val userModel = ViewModelProvider(this@LiveDataActivity).get(UserModel::class.java)
使用 ViewModelProvider.Factory 的代码:
val userModel = ViewModelProvider(this@LiveDataActivity, UserModelFactory(application)).get(UserModel::class.java)
不使用 ViewModelProvider.Factory 的两种情况:
【1】当 Model 继承 AndroidViewModel 时,并且 Model 只有 Application 参数时:
class UserModel(application: Application) : AndroidViewModel(application)
【2】当 Model 继承 ViewModel,并且 ViewModel 没有参数时:
class UserModel : ViewModel()
使用 ViewModelProvider.Factory 的情况:
【1】当 Model 继承 AndroidViewModel 时,并且 Model 有除了 Application 参数之外还有其它参数时:
class UserModel(application: Application, age: Int) : AndroidViewModel(application)
class UserModelFactory(private val application: Application) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(UserModel::class.java)) {
return UserModel(application, 3) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
【2】当 Model 继承 ViewModel,并且 Model 有参数时:
val userModel = ViewModelProvider(this@LiveDataActivity, UserModelFactory(application)).get(UserModel::class.java)
class UserModelFactory(private val application: Application) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(UserModel::class.java)) {
return UserModel(application) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
[本章完...]
网友评论