前言
ViewModel只能在Activty和Fragment里使用吗,能不能在View里使用呢?
假如我要提供一个View
,它包含一堆数据和状态,比如一个新闻列表、时刻表等。我是否可以再这个这个自定义View
里使用ViewModel
去管理数据呢?
在View中使用ViewModel
答案是肯定的!那么我们说干就干,看看到底怎么使用。
为了确保与宿主Avtivity/Fragment发生管理和便于宿主管理,我们需要使用ViewModelProvider
去创建ViewModel
,典型的使用方法如下:
ViewModelProvider(this,).get(CustomModel::class.java)
但这时就遇到了麻烦,ViewModelStoreOwner
去哪里弄,不仅没有ViewModelStoreOwner
,也没有ViewModelStore
啊。当然,你也可以打破规则,什么都不管,直接创建ViewModel
,但是我并不建议你这么做。这里我讲解一下如何老老实实的按照“规则”去使用它。
首先要获取到ViewModelStoreOwner
,有两种方法:
- 在你自定义View中实现它,并按照
ComponentActivity
的逻辑实现一遍; - 使用承载你自定义View的Activity或者Fragment的
ViewModelStoreOwner
在开始使用ViewModel之前,我们先准备一个自定义View,就弄一个简单的组合View:
class CustomView : RelativeLayout {
constructor(context: Context) : super(context) {
initView(context)
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
initView(context)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
initView(context)
}
private fun initView(context: Context) {
mViewModelStore = ViewModelStore()
LayoutInflater.from(context).inflate(R.layout.custom_layout, this, true)
}
}
布局文件:
<RelativeLayout
android:gravity="center"
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
and