进度指示器可直观地显示操作状态。它们利用动作来吸引用户的注意力,让用户知道该流程有多接近完成,例如加载或处理数据。它们还可以表示正在进行处理,而不考虑可能有多近完成。
请考虑以下三个可能会使用进度指示器的用例:
- 加载内容:从网络提取内容,例如加载用户个人资料的图片或数据。
- 文件上传:向用户提供有关上传可能需要多长时间的反馈。
- 处理时间长:当应用处理大量数据时,向用户传达已完成数据中的多少部分。
在 Material Design 中,有两种类型的进度指示器:
- 已确定:显示确切的进度。
- 不确定:持续呈现动画效果,而不考虑进度。
同样,进度指示器可以采用以下两种形式之一:
- 线性:从左到右填充的水平条。
- 圆形:描边逐渐延长直至覆盖整个圆周的圆形。
API Surface
虽然您可以使用多个可组合项来创建与 Material Design 一致的悬浮操作按钮,但它们的参数差异并不大。您应该注意以下关键参数:
progress
:指示器显示的当前进度。在0.0
和1.0
之间传递Float
。color
:实际指示器的颜色。也就是说,反映进度的组件部分会在进度完成时完全包围组件。trackColor
:绘制指示器的轨道的颜色。
确定指示符
确定性指示符可准确反映操作完成的程度。请使用 LinearProgressIndicator
或 CircularProgressIndicator
可组合项,并为 progress
形参传递值。
以下代码段提供了一个相对详细的示例。当用户按下该按钮时,应用既显示进度指示器,又启动一个逐渐增大 progress
值的协程。这会导致进度指示器依次向上迭代。
@Composable fun LinearDeterminateIndicator() { var currentProgress by remember { mutableStateOf(0f) } var loading by remember { mutableStateOf(false) } val scope = rememberCoroutineScope() // Create a coroutine scope Column( verticalArrangement = Arrangement.spacedBy(12.dp), horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth() ) { Button(onClick = { loading = true scope.launch { loadProgress { progress -> currentProgress = progress } loading = false // Reset loading when the coroutine finishes } }, enabled = !loading) { Text("Start loading") } if (loading) { LinearProgressIndicator( progress = { currentProgress }, modifier = Modifier.fillMaxWidth(), ) } } } /** Iterate the progress value */ suspend fun loadProgress(updateProgress: (Float) -> Unit) { for (i in 1..100) { updateProgress(i.toFloat() / 100) delay(100) } }
当加载部分完成时,上例中的线性指示器如下所示:
同样,圆形指示器如下所示:
不确定指示符
不确定性指示器并不反映操作已经完成的距离,而是使用运动向用户表明处理正在进行中,但不指定任何完成程度。
如需创建不确定的进度指示器,请使用 LinearProgressIndicator
或 CircularProgressIndicator
可组合项,但不要传入 progress
的值。以下示例演示了如何通过按下按钮来切换不确定性指示器。
@Composable fun IndeterminateCircularIndicator() { var loading by remember { mutableStateOf(false) } Button(onClick = { loading = true }, enabled = !loading) { Text("Start loading") } if (!loading) return CircularProgressIndicator( modifier = Modifier.width(64.dp), color = MaterialTheme.colorScheme.secondary, trackColor = MaterialTheme.colorScheme.surfaceVariant, ) }
以下是指示器处于活动状态时此实现的示例:
以下示例展示了同一实现,但使用的是 LinearProgressIndicator
,而不是 CircularProgressIndicator
。