Android ViewModel
介绍
在 Android 应用开发中,ViewModel 是一个非常重要的架构组件,它用于管理与 UI 相关的数据,并在配置更改(如屏幕旋转)时保持数据的持久性。ViewModel 的设计目的是将 UI 控制器(如 Activity 或 Fragment)与数据逻辑分离,从而使代码更加清晰、易于维护。
ViewModel 是 Android Jetpack 的一部分,它遵循生命周期感知的设计原则,确保数据在适当的生命周期内被管理和清理。
ViewModel 的基本概念
生命周期感知
ViewModel 的生命周期与 Activity 或 Fragment 的生命周期相关联,但它不会因为配置更改(如屏幕旋转)而被销毁。这意味着,当 Activity 或 Fragment 重新创建时,ViewModel 中的数据仍然可用。
数据持久性
ViewModel 的主要作用是存储和管理与 UI 相关的数据。通过将数据存储在 ViewModel 中,可以避免在每次配置更改时重新加载数据,从而提高应用的性能和用户体验。
如何使用 ViewModel
创建 ViewModel
要使用 ViewModel,首先需要在项目中添加 lifecycle-viewmodel
依赖项:
dependencies {
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
}
接下来,创建一个继承自 ViewModel
的类:
class MyViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data: LiveData<String> get() = _data
fun loadData() {
_data.value = "Hello, ViewModel!"
}
}
在这个例子中,MyViewModel
包含一个 LiveData
对象 _data
,它用于存储和观察数据。loadData
方法用于更新 _data
的值。
在 Activity 或 Fragment 中使用 ViewModel
要在 Activity 或 Fragment 中使用 ViewModel,可以使用 ViewModelProvider
来获取 ViewModel 的实例:
class MyActivity : AppCompatActivity() {
private lateinit var viewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
viewModel.data.observe(this, Observer { data ->
// 更新 UI
textView.text = data
})
viewModel.loadData()
}
}
在这个例子中,MyActivity
通过 ViewModelProvider
获取 MyViewModel
的实例,并观察 data
的变化。当 data
的值发生变化时,UI 会自动更新。
ViewModel 的实际应用场景
场景 1:屏幕旋转时保持数据
假设你正在开发一个天气应用,用户在输入城市名称后,应用会显示该城市的天气信息。如果用户在查看天气信息时旋转屏幕,Activity 会重新创建,但你不希望重新加载天气数据。这时,可以使用 ViewModel 来存储天气数据,确保在屏幕旋转后数据仍然可用。
class WeatherViewModel : ViewModel() {
private val _weatherData = MutableLiveData<Weather>()
val weatherData: LiveData<Weather> get() = _weatherData
fun loadWeather(city: String) {
// 模拟网络请求
_weatherData.value = Weather(city, "Sunny", 25)
}
}
在 Activity 中:
class WeatherActivity : AppCompatActivity() {
private lateinit var viewModel: WeatherViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_weather)
viewModel = ViewModelProvider(this).get(WeatherViewModel::class.java)
viewModel.weatherData.observe(this, Observer { weather ->
// 更新 UI
cityTextView.text = weather.city
weatherTextView.text = weather.condition
temperatureTextView.text = "${weather.temperature}°C"
})
viewModel.loadWeather("Beijing")
}
}
场景 2:共享数据 between Fragments
在一个多 Fragment 的应用中,你可能需要在多个 Fragment 之间共享数据。ViewModel 可以帮助你实现这一点。例如,在一个购物车应用中,你可以在一个 Fragment 中添加商品,而在另一个 Fragment 中显示购物车的总价。
class CartViewModel : ViewModel() {
private val _cartItems = MutableLiveData<List<CartItem>>()
val cartItems: LiveData<List<CartItem>> get() = _cartItems
fun addItem(item: CartItem) {
val currentItems = _cartItems.value ?: emptyList()
_cartItems.value = currentItems + item
}
}
在 Fragment 中:
class AddItemFragment : Fragment() {
private lateinit var viewModel: CartViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_add_item, container, false)
viewModel = ViewModelProvider(requireActivity()).get(CartViewModel::class.java)
addButton.setOnClickListener {
val item = CartItem("Product 1", 10.0)
viewModel.addItem(item)
}
return view
}
}
在另一个 Fragment 中:
class CartSummaryFragment : Fragment() {
private lateinit var viewModel: CartViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_cart_summary, container, false)
viewModel = ViewModelProvider(requireActivity()).get(CartViewModel::class.java)
viewModel.cartItems.observe(viewLifecycleOwner, Observer { items ->
val totalPrice = items.sumOf { it.price }
totalPriceTextView.text = "Total: $${totalPrice}"
})
return view
}
}
总结
ViewModel 是 Android 架构组件中的重要部分,它帮助开发者管理与 UI 相关的数据,并在配置更改时保持数据的持久性。通过将数据逻辑与 UI 控制器分离,ViewModel 使代码更加清晰、易于维护。
在实际开发中,ViewModel 可以用于多种场景,如屏幕旋转时保持数据、在多个 Fragment 之间共享数据等。掌握 ViewModel 的使用,将有助于你构建更加健壮和高效的 Android 应用。
附加资源与练习
- Android 官方文档:ViewModel
- 练习:尝试在一个简单的应用中实现 ViewModel,并在屏幕旋转时保持数据不变。
- 练习:在一个多 Fragment 的应用中使用 ViewModel 共享数据,并观察数据的变化。