进度指示器以视觉方式显示操作的状态。它们使用运动来吸引用户注意操作完成的进度,例如加载或处理数据。它们还可以表示正在进行处理,而无需参考完成的进度。
考虑以下三种可能使用进度指示器的用例
- 加载内容: 从网络获取内容时,例如加载图像或用户资料数据。
- 文件上传: 向用户提供有关上传可能需要多长时间的反馈。
- 长时间处理: 当应用程序处理大量数据时,向用户传达已完成的总进度。
在 Material Design 中,有两种类型的进度指示器。
- 确定性: 显示已完成的进度。
- 不确定性: 持续动画,不考虑进度。
同样,进度指示器可以采用以下两种形式之一。
- 线性: 从左到右填充的水平条。
- 圆形: 圆圈的描边长度不断增长,直到它包围圆圈的整个圆周。
API 表面
虽然您可以使用几个可组合项来创建与 Material Design 一致的进度指示器,但它们的参数差别不大。您应该牢记的关键参数如下:
progress
: 指示器显示的当前进度。传递Float
,介于0.0
和1.0
之间。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
。