android:viewmodel的例子
一,引入lifecycle相关库
1,在项目根目录下的build.gradle中配置脚本,增加:
buildscript{
ext {
lifecycle = "2.5.1"
}
}
编辑app下的build.gradle,增加:
// lifecycle相关
api "androidx.lifecycle:lifecycle-livedata-core-ktx:${rootProject.ext.lifecycle}"
api "androidx.lifecycle:lifecycle-livedata-ktx:${rootProject.ext.lifecycle}"
api "androidx.lifecycle:lifecycle-runtime-ktx:${rootProject.ext.lifecycle}"
api "androidx.lifecycle:lifecycle-viewmodel-ktx:${rootProject.ext.lifecycle}"
然后点击Sync Now
二,代码
1,viewmodel类
package com.example.okdemo1.viewmodel
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class CounterViewModel : ViewModel() {
// MutableLiveData 用于修改数据
private val _counter = MutableLiveData(0)
val counter: LiveData<Int> get() = _counter
// 在后台线程模拟耗时操作
fun increment() {
viewModelScope.launch(Dispatchers.Default) {
delay(1000) // 模拟耗时操作
_counter.postValue(_counter.value?.plus(1))
}
}
// 普通数据操作(无耗时)
fun reset() {
_counter.value = 0
}
}
2,activity代码
package com.example.okdemo1.activity
import android.os.Bundle
import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.example.okdemo1.R
import com.example.okdemo1.databinding.ActivityMainBinding
import com.example.okdemo1.databinding.ActivityVmBinding
import com.example.okdemo1.viewmodel.CounterViewModel
class VmActivity : AppCompatActivity() {
private lateinit var binding: ActivityVmBinding
private val viewModel: CounterViewModel by viewModels() // 委托初始化
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
binding = ActivityVmBinding.inflate(layoutInflater)
setContentView(binding.root)
// 监听 LiveData 变化(仅当 Activity 处于 STARTED/RESUMED 状态时触发)
viewModel.counter.observe(this) { count ->
binding.tvCount.text = "Count: $count"
binding.progressBar.visibility = if (count > 5) View.VISIBLE else View.GONE
}
//增加
binding.btnIncrement.setOnClickListener {
viewModel.increment()
}
//重置
binding.btnReset.setOnClickListener {
viewModel.reset()
}
}
}
activity xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.VmActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
android:orientation="vertical">
<TextView
android:id="@+id/tvCount"
android:text="Count: 0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="44sp"/>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar"
android:visibility="gone" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnIncrement"
android:textSize="44sp"
android:text="增长"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnReset"
android:textSize="44sp"
android:text="重置"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
三,测试效果:

浙公网安备 33010602011771号