先搬一下官方介绍
- ViewModel旨在以注重生命周期的方式存储和管理界面相关的数据,让数据可在发生屏幕旋转等配置更改后继续存在。
- LiveData是一种可观察的数据存储器类。LiveData 具有生命周期感知能力,遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
简单来说,ViewModel在屏幕旋转等配置更改期间,对象会保留,储存在ViewModel的数据自然也会保留。LiveData以观察者模式,仅在组件处于激活状态(onStart,onResume)时更新数据,当组件被销毁时,系统会退订它们。一般来讲ViewModel会配合LiveData使用,LiveData初始化在ViewModel中。
下面上代码
build.gradle依赖
dependencies {
...
def lifecycle_version = "2.2.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
}
MainModel
class MainModel : ViewModel() {
//初始化LiveData,观察的数据类型即泛型String类型
val contentLiveData: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
}
MainActivity
class MainActivity : AppCompatActivity() {
private lateinit var model: MainModel
private var i = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//创建ViewModel
model = ViewModelProvider(this).get(MainModel::class.java)
//回调方法中更新ui
val contentObserver = Observer<String> { content ->
tvContent.text = content
}
//订阅
model.contentLiveData.observe(this, contentObserver)
//按钮 模拟更新数据操作
btContent.setOnClickListener {
i++
//通过LiveData.setValue()方法通知数据更新,稍后回调Observer接口方法更新ui
model.contentLiveData.value = "content+$i"
}
}
}
ViewModel用于Activity内多个fragment数据共享
FragmentModel
class FragmentModel : ViewModel() {
val fragmentLiveData: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
}
FirstFragment
class FirstFragment : Fragment() {
private lateinit var model: FragmentModel
private var i = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = ViewModelProvider(this).get(FragmentModel::class.java)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btFirst.setOnClickListener {
i++
model.fragmentLiveData.value = "content+$i"
}
}
}
SecondFragment
class SecondFragment : Fragment() {
private lateinit var model: FragmentModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
model = ViewModelProvider(this).get(FragmentModel::class.java)
model.fragmentLiveData.observe(this, Observer { content ->
tvSecond.text = content
})
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
}
同Activity下Fragment获取到的ViewModel实例是同一个,相较于接口回调更简洁。
ViewModel配合协程使用
class MainModel : ViewModel() {
val contentLiveData: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
init {
viewModelScope.launch {
val deferred = async(Dispatchers.IO){
"result"
}
val result = deferred.await()
contentLiveData.value = result
}
}
}
Lifecycle配合协程使用
class FirstFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycleScope.launch {
}
}
}
网友评论