Jetpack--->ViewModel知识点梳理
-
概念
ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel类让数据可在发生屏幕旋转等配置更改后继续留存。比如说在屏幕发生旋转的时候,像Fragment和Activity这种UI控制器就会重新创建新实例,但是,ViewModel会存活,并不会创建新的实例,那么在ViewModel中的数据就不会丢失。但是,ViewModel的初始化并不是我们直接通过使用该Class对象进行创建,而是通过特定的方式进行初始化实例,比如,ViewModelProvider以及属性委派(activity-ktx中的扩展函数viewModels())。下面就介绍ViewModel的基本使用
-
基本用法
-
使用ViewModelProvider
我们一般是将LiveData对象放在我们的ViewModel的类中,关于LiveData的介绍在Jetpack -->LiveData的知识梳理博客中进行介绍,这里就不多介绍了。
class UserViewModel : ViewModel() {// 无参构造器 private val _user = MutableLiveData<User>() var user: LiveData<User> = _user }
那么在我们的UI控制器Activity当中,就需要通过ViewModelProvider进行初始化ViewModel实例。
class MainActivity : AppCompatActivity() { private var viewModel: UserViewModel? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) // 初始化ViewModel viewModel = ViewModelProvider(this).get(UserViewModel::class.java) } }
关于ViewModelProvider的介绍:这个现在已经使用属性委派来进行ViewModel的初始化(更方便),后面介绍属性委派给ViewModel实例初始化。
-
如果响应的ViewModel的实例已经存在,那么ViewModelProvider会返回这个已经的存在的实例,否则创建一个新的ViewModel实例返回。
-
ViewModel的生命周期是和它绑定的Scope(ViewModelStoreOwner)相联系的,只要它所在的Scope存活,那么它的实例就会一直存在,知道Scope被销毁。下图就是ViewModel的生命周期。
-
上面的初始化实例ViewModel的构造器是没有参数的,下面介绍带有参数的ViewModel的初始化的步骤。
class UserViewModel(val viewModelName: String) : ViewModel() {// 有参构造器 private val _user = MutableLiveData<User>() var user: LiveData<User> = _user }
需要一个UserViewModelProvider,这个类实现ViewModelProvider.Factory接口中的create方法,就是创建带有参数的ViewModel实例,具体操作如下。
class UserViewModelProvider: ViewModelProvider.Factory{ @Suppress("UNCHECKED_CAST") override fun <T : ViewModel?> create(modelClass: Class<T>): T { return UserViewModel("userViewModel") as T } } class MainActivity : AppCompatActivity() { private var viewModel: UserViewModel? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) // 方式1: 初始化ViewModel viewModel = ViewModelProvider(this,UserViewModelProvider()) .get(UserViewModel::class.java) // 方式2: 直接使用匿名内部类写法 userViewModel = ViewModelProvider(this,object : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun <T : ViewModel?> create(modelClass: Class<T>): T { return UserViewModel("userViewModel") as T } }).get(UserViewModel::class.java) } }
-
-
使用属性委派来初始化ViewModel(ComponentActivity.viewModels())
按照上面的分为带有参数的ViewModel和不带参数的ViewModel。
-
无参
class MainActivity : AppCompatActivity() { private val userViewModel by viewModels<UserViewModel>() // 或者 private val userViewModel: UserViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) } }
-
有参
class MainActivity : AppCompatActivity() { private val userViewModel by viewModels<UserViewModel> { object : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun <T : ViewModel?> create(modelClass: Class<T>): T { return UserViewModel("userViewModel") as T } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) } }
-
-