进度指示器会直观地显示操作的状态。它们会使用动画效果来提醒用户进程(例如加载或处理数据)的完成进度。它们还可以表示正在进行处理,而无需提及完成进度。
请考虑以下三种可能需要使用进度指示器的用例:
- 加载内容:从网络提取内容时,例如加载 图片或用户个人资料数据。
- 文件上传:向用户反馈上传可能需要的时间。
- 长时间处理:当应用处理大量数据时, 向用户传达已完成的总量。
在 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 { mutableFloatStateOf(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。