Jetpack--->ViewModel知识点梳理

Jetpack--->ViewModel知识点梳理

  1. 概念

    ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel类让数据可在发生屏幕旋转等配置更改后继续留存。比如说在屏幕发生旋转的时候,像FragmentActivity这种UI控制器就会重新创建新实例,但是,ViewModel会存活,并不会创建新的实例,那么在ViewModel中的数据就不会丢失。但是,ViewModel的初始化并不是我们直接通过使用该Class对象进行创建,而是通过特定的方式进行初始化实例,比如,ViewModelProvider以及属性委派(activity-ktx中的扩展函数viewModels())。下面就介绍ViewModel的基本使用

  2. 基本用法

    1. 使用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实例初始化。

      1. 如果响应的ViewModel的实例已经存在,那么ViewModelProvider会返回这个已经的存在的实例,否则创建一个新的ViewModel实例返回。

      2. ViewModel的生命周期是和它绑定的Scope(ViewModelStoreOwner)相联系的,只要它所在的Scope存活,那么它的实例就会一直存在,知道Scope被销毁。下图就是ViewModel的生命周期。
        Jetpack--->ViewModel知识点梳理

      3. 上面的初始化实例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)
            }
        }
        
    2. 使用属性委派来初始化ViewModel(ComponentActivity.viewModels())

      按照上面的分为带有参数的ViewModel和不带参数的ViewModel

      1. 无参

        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)
        
            }
        }
        
      2. 有参

        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)
        
            }
        }
        
上一篇:Jetpack--->LiveData知识点梳理


下一篇:Jetpack 新成员 Hilt 实践(一,真是恍然大悟啊