和传统方式的核心区别:
传统方式需要手动调用 textView.setText() 更新 UI
传统方式需要自己处理屏幕旋转的数据保存
传统方式可能在 Activity 销毁后更新 UI 导致崩溃
CounterViewModel.kt
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
// ViewModel 负责管理数据和业务逻辑
class CounterViewModel : ViewModel() {
// 私有可变的 LiveData(内部修改)
private val _count = MutableLiveData(0)
// 公开不可变的 LiveData(供 UI 观察)
val count: LiveData<Int> = _count
// 增加计数的方法
fun increment() {
// 获取当前值,加1后更新(主线程用setValue)
_count.value = _count.value?.plus(1)
}
// 重置计数的方法
fun reset() {
_count.value = 0
}
}
MainActivity.kt
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import com.example.livedatademo.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel: CounterViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 初始化 DataBinding
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// 获取 ViewModel 实例
viewModel = ViewModelProvider(this)[CounterViewModel::class.java]
// 观察 LiveData 变化,自动更新 UI
viewModel.count.observe(this) { newCount ->
// 数据变化时自动执行,已在主线程
binding.tvCount.text = "当前计数: $newCount"
}
// 绑定按钮点击事件
binding.btnIncrement.setOnClickListener {
viewModel.increment() // 只修改数据,UI 自动更新
}
binding.btnReset.setOnClickListener {
viewModel.reset() // 只修改数据,UI 自动更新
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="16dp">
<TextView
android:id="@+id/tvCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:marginBottom="32dp"/>
<Button
android:id="@+id/btnIncrement"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加1"
android:layout_marginBottom="16dp"/>
<Button
android:id="@+id/btnReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="重置"/>
</LinearLayout>
</layout>