implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
class StartViewModel: ViewModel() {
}
class StartActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: StartViewModel = ViewModelProvider(this).get(StartViewModel::class.java)
}
}
首先添加ktx依赖
implementation "androidx.fragment:fragment-ktx:1.2.4"
然后获取ViewModel实例写法变这样
class StartActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: StartViewModel by viewModels()
}
}
class StartViewModel(val param: String) : ViewModel() {
}
怎么获取了传递了参数的ViewModel实例?
通过实现ViewModelProvider.Factory接口,创建ViewModelFactory类
@Suppress("UNCHECKED_CAST")
class StartViewModelFactory(private val param: String) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return StartViewModel(param) as T
}
}
val number = MutableLiveData<Int>()
getValue()、setValue()、postValue()
viewModel.number.observe(this, Observer { number ->
println(number)
})
首先添加依赖
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
然后观察LiveData对象的写法变成了这样
viewModel.number.observe(this) { number ->
println(number)
}
private val _number = MutableLiveData<Int>()
val number: LiveData<Int> get() = _number
当外部调用number对象时,实际上获得的是_number的实例,但是无法给counter设置数据了
什么场景下用map?
比如有一个User对象,他有三个属性:name,age,sex,但是我在MainActivity中只用到了User里的name属性。
data class User(var name: String, var age: Int, var sex: String)
val user = MutableLiveData<User>()
val userLiveData = MutableLiveData<User>()
val userName: LiveData<String> = Transformations.map(userLiveData) { user ->
user.name
}
使用场景:当ViewModel中的某个LiveData对象是调用另外的方法获取的
object Repository {
fun getUser(userId: String): LiveData<User> {
val liveData = MutableLiveData<User> ()
liveData.value = User(userId, userId, 0)
return liveData
}
}
这里每次调用getUser方法都会返回一个新的LiveData对象
class StartViewModel(val param: String) : ViewModel() {
fun getUser(userId: String): LiveData<User> {
return Repository.getUser(userId)
}
}
如果我们还是直接观察这个StartViewModel中的getUser方法返回的LvieData对象,显然是错误的,因为这个方法返回的是Repository中的getUser方法的返回值,但是Repository中的getUser方法返回的始终是一个新的LiveData对象,这样我们就无法观察到LiveData对象值的变化。(这个问题是很常见的,因为在官方推荐的MVVM架构中,我们的数据操作都是放到Repository层的)
使用switchMap解决这个问题
private val userIdLiveData = MutableLiveData<String>()
var user: LiveData<User> = Transformations.switchMap(userIdLiveData) { userId ->
Repository.getUser(userId)
}
fun getUser(userId: String) {
userIdLiveData.value = userId
}
这里swtichMap的工作流程
当Activity调用ViewModel中的getUser方法来获取用户数据时,将传入的userId设置到userLiveData中,一旦userLiveData的值发生变化,那么观察userIdLiveData的switchMap就会执行,去调用Repository.getUser()方法获取真正的用户数据,同时switchMap会将Repository.getUser()方法返回的LiveData对象转换成一个可观察的LIveData对象,Activity只需要去观察这个返回的user就可以了。