Android Compose 中的 UI 状态魔法:优雅处理加载、空状态和数据展示
在Jetpack Compose中处理UI界面状态的这种情况,我们可以使用一个密封类(sealed class)来表示不同的UI状态,然后根据状态来显示相应的UI。以下是一个实现这种功能的示例:
1. 首先,定义一个表示UI状态的密封类:
sealed class UiState {
object Initial : UiState()
object Loading : UiState()
object Empty : UiState()
data class Success(val data: List<Item>) : UiState()
data class Error(val message: String) : UiState()
}
1. 在ViewModel中管理这个状态:
class MyViewModel : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Initial)
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
fun loadData() {
viewModelScope.launch {
_uiState.value = UiState.Loading
try {
val result = repository.fetchData() // 假设这是一个挂起函数
_uiState.value = if (result.isEmpty()) {
UiState.Empty
} else {
UiState.Success(result)
}
} catch (e: Exception) {
_uiState.value = UiState.Error("加载失败: ${e.message}")
}
}
}
}
1. 在Compose UI中使用这个状态:
fun MyScreen(viewModel: MyViewModel = viewModel()) {
val uiState by viewModel.uiState.collectAsState()
val scaffoldState = rememberScaffoldState()
LaunchedEffect(key1 = true) {
viewModel.loadData()
}
Scaffold(
scaffoldState = scaffoldState
) { padding ->
Box(modifier = Modifier.padding(padding).fillMaxSize()) {
when (uiState) {
is UiState.Initial -> Text("准备加载数据")
is UiState.Loading -> CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
is UiState.Empty -> Text("没有数据", modifier = Modifier.align(Alignment.Center))
is UiState.Success -> {
LazyColumn {
items((uiState as UiState.Success).data) { item ->
// 显示每个item
Text(item.toString())
}
}
LaunchedEffect(key1 = uiState) {
scaffoldState.snackbarHostState.showSnackbar("数据加载成功")
}
}
is UiState.Error -> {
Text((uiState as UiState.Error).message, modifier = Modifier.align(Alignment.Center))
LaunchedEffect(key1 = uiState) {
scaffoldState.snackbarHostState.showSnackbar("加载失败")
}
}
}
}
}
}
这个实现做到了以下几点:
1. 使用
UiState
密封类来表示所有可能的UI状态。2. 在ViewModel中管理状态,并提供加载数据的方法。
3. 在Compose UI中,使用
when
表达式根据不同的状态显示不同的UI。4. 使用
CircularProgressIndicator
显示加载进度。5. 当数据加载成功时,使用
LazyColumn
显示数据。6. 使用
Scaffold
和SnackBar
来显示加载成功或失败的消息。
这种方法提供了一个清晰和可扩展的方式来管理UI状态,使得添加新的状态或修改现有状态变得简单。同时,它也符合Jetpack Compose的声明式UI设计理念。