ComposeUI中的ViewModel视图管理类
基本概念
在讲解ViewModel之前,我们需要先理解数据类与普通类的区别。
- Name
数据类(data class)
- Type
- data class
- Description
- 自动生成equals()、hashCode()等方法
- 适合简单的数据模型
- 用于UI状态
- 不可变性和线程安全
- Name
普通类(class)
- Type
- class
- Description
- 标准类型
- 适合复杂的数据管理
- 用于ViewModel
- 支持继承和多态
ViewModel基础示例
// 数据模型使用data class
data class User(
val name: String,
val age: Int
)
// ViewModel使用class
class UserViewModel : ViewModel() {
var user by mutableStateOf<User?>(null)
private set
fun updateName(newName: String) {
user?.let {
user = it.copy(name = newName)
}
}
}
ViewModel的角色
ViewModel在ComposeUI中的主要职责。
- Name
数据管理
- Type
- data
- Description
- 状态管理
- 数据处理
- 业务逻辑
- 数据持久化
- Name
视图通信
- Type
- communication
- Description
- 数据流
- 事件处理
- 状态更新
- 生命周期管理
ViewModel职责示例
class TodoViewModel : ViewModel() {
var todos by mutableStateOf<List<Todo>>(emptyList())
private set
var isLoading by mutableStateOf(false)
private set
fun fetchTodos() {
viewModelScope.launch {
isLoading = true
try {
val result = todoRepository.getTodos()
todos = result
} catch (e: Exception) {
handleError(e)
} finally {
isLoading = false
}
}
}
}
状态管理
ViewModel中的状态管理技术。
- Name
状态流
- Type
- state
- Description
- StateFlow
- MutableStateFlow
- SharedFlow
- 状态更新
- Name
生命周期
- Type
- lifecycle
- Description
- 初始化
- onCleared
- 协程作用域
- 依赖注入
状态管理示例
class AuthViewModel : ViewModel() {
var uiState by mutableStateOf<AuthUiState>(AuthUiState.Initial)
private set
fun checkAuthState(state: AuthState) {
uiState = when(state) {
is AuthState.Authenticated ->
AuthUiState.Authenticated(state.user)
else -> AuthUiState.Unauthenticated
}
}
fun signOut() {
viewModelScope.launch {
// 处理登出逻辑
uiState = AuthUiState.Unauthenticated
}
}
}
最佳实践
ViewModel的设计原则和最佳实践。
- Name
设计原则
- Type
- principles
- Description
- 单一职责
- 依赖注入
- 内存管理
- 错误处理
- Name
常见问题
- Type
- issues
- Description
- 避免循环引用
- 异步操作处理
- 状态同步
- 测试性
ViewModel最佳实践
class ProductViewModel : ViewModel() {
var products by mutableStateOf<List<Product>>(emptyList())
private set
var isLoading by mutableStateOf(false)
private set
var error by mutableStateOf<Error?>(null)
private set
fun fetchProducts() {
viewModelScope.launch {
isLoading = true
error = null
try {
products = productService.fetchProducts()
} catch (e: Exception) {
error = Error(e.message)
} finally {
isLoading = false
}
}
}
}