在compose中,可以使用mutableState 创建可观察的对象,为了让可观察数据在compose函数重组后依旧可以保持最新。可以使用remember api 将数据存储在内存中
三种写法:
val mutableState = remember { mutableStateOf("") }
val value by remember { mustableStateOf("") }
val {value,setValue} = remember { mustableState{""} }
注意:如果要对list进行可变重组,需要使用mustateStateListOf(...),可以对增删改进行重组。如果是mustateListOf(list(...)),可以对list整个重新赋值进行重组。
与 ViewModel 结合,将列表状态提升到 ViewModel 中,与UI逻辑分离。
class TodoViewModel : ViewModel() {
// 在ViewModel中使用可观察的StateFlow
private val _todos = MutableStateFlow<List<TodoItem>>(emptyList())
val todos: StateFlow<List<TodoItem>> = _todos.asStateFlow()
fun addTodo(text: String) {
_todos.update { currentList ->
currentList + TodoItem(
id = Random.nextInt(),
text = text,
isDone = false
)
}
}
}
@Composable
fun TodoScreen(viewModel: TodoViewModel = viewModel()) {
// 在Compose中收集StateFlow
val todoList by viewModel.todos.collectAsStateWithLifecycle()
Column {
LazyColumn {
items(todoList) { item ->
TodoItemView(item)
}
}
// 通过ViewModel更新状态
Button(onClick = { viewModel.addTodo("New Task") }) {
Text("Add")
}
}
}
性能优化:避免不必要的重组
对于大型列表,使用 derivedStateOf 或 remember 计算派生值,避免在每次重组时都重新计算。
@Composable
fun TodoSummary(todos: List<TodoItem>) {
// 仅当todos变化时,才重新计算已完成的数量
val completedCount by remember(todos) {
derivedStateOf {
todos.count { it.isDone }
}
}
Text("已完成: $completedCount / ${todos.size}")
}