Jetpack Compose:切换底部导航时先显示加载器再渲染页面
实现即时跳转+加载状态的底部导航页面切换
要实现点击底部导航后立即跳转显示加载器,待API返回数据再渲染页面,核心是将页面的数据加载逻辑从组件初始化同步执行改为异步触发,并在页面内部维护加载状态,具体实现方案如下:
1. 重构页面组件,添加状态管理
每个页面组件需内部维护加载状态,进入页面后立即触发异步API请求,根据请求状态切换UI:
@Composable fun RenderTransactionsScreen(context: Context) { // 维护加载状态,初始为true val isLoading = remember { mutableStateOf(true) } // 存储页面数据,根据实际业务调整类型 val transactionsData = remember { mutableStateOf<List<Transaction>>(emptyList()) } val errorMessage = remember { mutableStateOf<String?>(null) } // 页面首次进入时触发API请求 LaunchedEffect(Unit) { try { // 替换为你的实际后端API请求逻辑 val data = fetchTransactionsFromApi(context) transactionsData.value = data } catch (e: Exception) { errorMessage.value = e.localizedMessage } finally { // 请求完成(成功/失败)都结束加载状态 isLoading.value = false } } // 根据状态渲染对应UI when { isLoading.value -> { // 加载中:居中显示圆形加载器 Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { CircularProgressIndicator(color = MaterialTheme.colorScheme.primary) } } errorMessage.value != null -> { // 加载失败:显示错误提示(可选) Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Text(text = errorMessage.value ?: "加载失败", color = MaterialTheme.colorScheme.error) } } else -> { // 加载完成:渲染完整页面内容 TransactionsContent(data = transactionsData.value) } } } // 实际API请求需改为挂起函数,避免阻塞UI线程 suspend fun fetchTransactionsFromApi(context: Context): List<Transaction> { // 模拟网络延迟,实际场景替换为Retrofit/OkHttp请求 delay(1500) return listOf( Transaction("午餐消费", "2024-05-20", 45.0), Transaction("交通补贴", "2024-05-19", 100.0) ) } // 页面核心内容组件(提取原RenderTransactionsScreen的渲染逻辑) @Composable fun TransactionsContent(data: List<Transaction>) { LazyColumn(modifier = Modifier.fillMaxSize()) { items(data) { transaction -> ListItem( headlineContent = { Text(transaction.title) }, supportingContent = { Text(transaction.date) }, trailingContent = { Text("¥${transaction.amount}") } ) } } } // 模拟数据类,根据实际业务替换 data class Transaction(val title: String, val date: String, val amount: Double)
2. 对其他页面执行同样改造
按照上述模式,修改RenderSummaryScreen和RenderProfileScreen,确保每个页面都能在进入时立即显示加载器,异步加载数据。
3. 保持原有导航逻辑不变
原有的NavigationController和Navigation组件无需修改,因为NavHost在调用navController.navigate时会立即切换到目标页面组件,我们已经将页面的同步加载逻辑改为异步,因此页面会先显示加载器,不会阻塞跳转流程。
关键细节说明
- LaunchedEffect(Unit):确保页面首次组合时仅触发一次API请求,避免重复请求。
- 状态驱动UI:用
mutableStateOf维护加载状态、数据和错误信息,Compose会自动根据状态变化重组UI。 - 异步请求:API请求必须使用挂起函数(
suspend修饰),保证不会阻塞UI线程,确保跳转的即时性。
内容的提问来源于stack exchange,提问作者Shailesh
相关产品推荐
相关产品推荐

