官网镇楼 ViewModel 概览 | Android 开发者 | Android Developers
https://developer.android.google.cn/topic/libraries/architecture/viewmodel?hl=zh_cn#kotlin
ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。
ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。
ViewModel 是用于管理数据的,界面上的数据,都应该放到 ViewModel 中,简化 Activity 和 Fragment 中的逻辑。
开始使用。
1.添加依赖
dependencies {
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
}
2.创建 ViewModel
创建 MyViewModel ,继承 ViewModel 。
所有与页面相关的数据都放在 ViewModel 中。
本例简单,就放一个数据。
import androidx.lifecycle.ViewModel
class MyViewModel : ViewModel() {
/**
* 所有与页面相关的数据都放在 ViewModel 中
* */
var num = 0
}
3.实例化 ViewModel 和使用
class ViewModelActivity : AppCompatActivity() {
lateinit var myViewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view_model)
sp = getPreferences(Context.MODE_PRIVATE)
myViewModel = ViewModelProvider(this).get(MyViewModel::class.java)
button1.setOnClickListener {
myViewModel.num++
refreshText()
}
refreshText()
}
fun refreshText(){
textview.text = myViewModel.num.toString()
}
}
lateinit
是 Kotlin 的关键字,用于延迟初始化。
如例子中的 ViewModelProvider(this).get(MyViewModel::class.java)
,
实例化 ViewModel 的格式是: ViewModelProvider(<要用ViewModel的Activity或者Fragment的实例>).get(<创建的ViewModel>::class.java)
补充布局,很简单,就一个 TextView 、一个 Button,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textview"
android:gravity="center"
android:textSize="30sp"
android:textColor="@color/design_default_color_secondary"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/button1"
android:text="Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
这就是 ViewModel 的基本使用了。
4.给ViewModel传递数据
上面是例子是从 ViewModel 读取数据,怎么给ViewModel传递数据呢?
用 ViewModelProvider.Factory
。
4.1 创建 ViewModelProvider.Factory
创建 MyViewModelFactory ,继承 ViewModelProvider.Factory ,重写 create() 方法。
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
class MyViewModelFactory(private val data:Int) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
//TODO("Not yet implemented")
return MyViewModel(data) as T
}
}
4.2 修改 ViewModel ,构造函数中是要传递的数据
import androidx.lifecycle.ViewModel
class MyViewModel(data : Int) : ViewModel() {
/**
* 所有与页面相关的数据都放在 ViewModel 中
* */
var num = data
}
4.3 使用 ViewModelProvider.Factory 实例化 ViewModel
class ViewModelActivity : AppCompatActivity() {
lateinit var myViewModel: MyViewModel
lateinit var sp: SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view_model)
sp = getPreferences(Context.MODE_PRIVATE)
val last = sp.getInt("key_last_data", 0)
//myViewModel = ViewModelProvider(this).get(MyViewModel::class.java)
myViewModel = ViewModelProvider(this, MyViewModelFactory(last)).get(MyViewModel::class.java)
button1.setOnClickListener {
myViewModel.num++
refreshText()
}
refreshText()
}
fun refreshText(){
textview.text = myViewModel.num.toString()
}
override fun onPause() {
super.onPause()
sp.edit {
putInt("key_last_data", myViewModel.num)
}
}
}
原来的实例化方法是: myViewModel = ViewModelProvider(this).get(MyViewModel::class.java) ,
对应 ViewModelProvider(@NonNull ViewModelStoreOwner owner)
使用 ViewModelProvider.Factory 后,实例化方法是 :
myViewModel = ViewModelProvider(this, MyViewModelFactory(last)).get(MyViewModel::class.java) ,
对应 ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory)
然后使用 SharedPreferences 保存数据。