ViewModel是android体系结构组件的一部分。 Android体系结构组件是用于构建健壮,干净和可扩展的应用程序的组件。 Android体系结构组件包含一些类来管理UI组件和数据持久性。 ViewModel类旨在以生命周期感知的方式存储和管理与UI相关的数据。 ViewModel类用于存储数据,即使配置更改(如旋转屏幕)也是如此。 ViewModel是Android Jetpack Architecture组件中最关键的类之一,它支持UI组件的数据。其目的是保存和管理与UI相关的数据。此外,它的主要函数是保持完整性,并允许在屏幕旋转等配置更改期间为数据提供服务。 Android设备中的任何类型的配置更改都倾向于重新创建应用程序的整个活动。这意味着,如果数据没有被保存并从被销毁的活动中正确恢复,则数据将丢失。为避免这些问题,建议将所有UI数据存储在ViewModel中,而不是将其存储在活动中。
活动必须扩展ViewModel类以创建视图模型:
class MainActivityViewModel : ViewModel() {
………
……..
}
在Android App中实现ViewModel
Android体系结构组件为UI控制器提供了ViewModel帮助器类,该类负责为UI准备数据。 ViewModel对象会在配置更改期间自动保留,我们将在以下示例中看到这一点。现在让我们进入代码,
步骤1:在build.gradle文件中添加这些依赖项
def lifecycle_version = “2.3.0”
// ViewModel
implementation “androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version”
implementation “androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version”
implementation “androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version”
implementation “androidx.core:core-ktx:1.3.2”
另外,将以下依赖项添加到build.gradle(Module:app)文件中。我们添加这两个依赖项是因为避免在MainActivity.kt文件中使用findViewById() 。尝试一下,否则使用常规方法,例如findViewById() 。
apply plugin: ‘kotlin-android’
apply plugin: ‘kotlin-android-extensions’
下面的代码不使用ViewModel
步骤2:使用activity_main.xml文件
导航到应用程序> res>布局> activity_main.xml,然后将以下代码添加到该文件中。以下是activity_main.xml文件的代码。
XML
Kotlin
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var number = 0
textView.text = number.toString()
button.setOnClickListener {
number++
textView.text = number.toString()
}
}
}
Kotlin
import androidx.lifecycle.ViewModel
class MainActivityViewModel : ViewModel() {
var number = 0
fun addOne() {
number++
}
}
Kotlin
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// view model instance
var viewModel: MainActivityViewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)
// setting text view
textView.text = viewModel.number.toString()
//handling button click event
button.setOnClickListener {
viewModel.addOne()
textView.text = viewModel.number.toString()
}
}
}
步骤3:使用MainActivity.kt文件
转到MainActivity.kt文件,并参考以下代码。下面是MainActivity.kt文件的代码。
科特林
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var number = 0
textView.text = number.toString()
button.setOnClickListener {
number++
textView.text = number.toString()
}
}
}
输出:
现在只需单击按钮3至4次,您将在屏幕上看到递增的数字。现在,只需尝试旋转模拟器或设备即可。
您会看到数字变为0,问题是为什么?如何通过旋转屏幕擦除值。好了,要得到答案,我们必须了解一些有关ViewModel生命周期的知识。
在上面的图像中,当我们创建活动时,系统会在onStart()之后调用onCreate(),然后再调用onResume(),但是当我们旋转屏幕时,我们的活动将被销毁,并且在旋转之后,系统会再次依次调用onCreate()和其他函数。由于我们的活动遭到破坏,我们的活动数据也消失了。
为了克服这个问题,我们使用ViewModels来保存数据,即使配置发生了变化(例如屏幕旋转)也是如此。上图显示了ViewModel范围,即使进行了任何配置更改,数据仍然是持久的。当系统调用活动对象的onCreate()方法时,通常通常是第一次请求ViewModel。在整个活动的生命周期中,例如旋转设备屏幕时,系统可能会多次调用onCreate()。从您首次请求ViewModel到活动完成并销毁为止,ViewModel一直存在。
ViewModel示例
步骤1:创建Kotlin类文件MainActivityViewModel.kt。我们的MainActivity类文件扩展了ViewModel类。
Refer to this article: How to Create Classes in Android Studio?
科特林
import androidx.lifecycle.ViewModel
class MainActivityViewModel : ViewModel() {
var number = 0
fun addOne() {
number++
}
}
步骤2:使用MainActivity.kt文件
转到MainActivity.kt文件并更新以下代码。下面是MainActivity.kt文件的代码。在代码内部添加了注释,以更详细地了解代码。
科特林
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// view model instance
var viewModel: MainActivityViewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)
// setting text view
textView.text = viewModel.number.toString()
//handling button click event
button.setOnClickListener {
viewModel.addOne()
textView.text = viewModel.number.toString()
}
}
}
输出:
即使旋转了屏幕,我们也获得了相同的值。就是这样,这是ViewModel的基础,我们稍后将介绍视图模型的许多其他高级内容。
ViewModel组件的优点
- 在配置更改期间帮助数据管理
- 减少UI错误和崩溃
- 软件设计最佳实践