Material 3 进度组件识别:LinearProgressIndicator、CircularProgressIndicator 的 Compose API
在 UI 自动化测试中,准确识别待测进度组件是编写可靠断言的前提。Material 3 提供了两种互补的进度指示器:LinearProgressIndicator(线性)和 CircularProgressIndicator(圆形)。本章从测试视角梳理两者的 Compose API 核心参数、构造方式与可观察属性,为后续在测试代码中通过 Semantics 树定位进度元素奠定基础。
测试前提: 确保项目已引入 Material 3 依赖。在
build.gradle.kts (模块级) 中添加:
dependencies {
implementation("androidx.compose.material3:material3:1.2.0")
androidTestImplementation("androidx.compose.ui:ui-test-junit4:1.6.0")
}
2.1 核心 API 对比
| 参数 / 特性 | LinearProgressIndicator | CircularProgressIndicator |
|---|---|---|
| 形状 | 水平长条 | 圆形轨迹 |
| 方向 | 水平 (可设置 track 宽度) | 无方向性 (旋转动画) |
| 进度范围 | 0f .. 1f (确定模式) / null (不确定模式) | 0f .. 1f (确定模式) / null (不确定模式) |
| 关键参数 | progress, trackColor, indicatorColor, strokeWidth | progress, trackColor, indicatorColor, strokeWidth |
| Semantics 角色 | ProgressBar | ProgressBar |
| 无障碍值 | 自动映射 progress 为 rangeValue | 自动映射 progress 为 rangeValue |
| 测试 Tag 注入 | Modifier.testTag("myLinear") | Modifier.testTag("myCircular") |
2.2 LinearProgressIndicator API 详解
线性进度条通常用于页面顶部或卡片内,展现连续任务的整体进度。构造函数签名如下(省略装饰参数):
@Composable
fun LinearProgressIndicator(
progress: Float?, // null → 不确定模式; 0f..1f → 确定模式
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colorScheme.primary,
trackColor: Color = MaterialTheme.colorScheme.surfaceVariant,
strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth,
... // 其他 Material 3 特定参数
)
- 确定模式示例:
progress = 0.5f→ 填充 50% - 不确定模式示例:
progress = null→ 持续滚动动画(未显示具体百分比) - 测试定位:通过
onNodeWithTag("linearProgress")或onNode(hasProgressBarRole())获取
测试代码片段(确定模式):
@get:Rule
val composeTestRule = createComposeRule()
// 在 Compose 中设置
composeTestRule.setContent {
val progress by remember { mutableStateOf(0.3f) }
LinearProgressIndicator(
progress = progress,
modifier = Modifier.testTag("downloadProgress")
)
}
// 断言
composeTestRule
.onNodeWithTag("downloadProgress")
.assertExists()
.assertSemanticsMatcher("progressValue") {
it.getFloat(SemanticsProperties.ProgressBarRangeInfo)?.current ?: 0f
}
2.3 CircularProgressIndicator API 详解
圆形进度条常用于加载转圈、文件上传等场景。API 结构与线性版本高度一致:
@Composable
fun CircularProgressIndicator(
progress: Float?,
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colorScheme.primary,
trackColor: Color = MaterialTheme.colorScheme.surfaceVariant,
strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth,
... // 大小、间隙等参数
)
- 确定模式:
progress = 0.75f→ 圆弧角度为 270° - 不确定模式:
progress = null→ 圆环连续旋转 - 测试中区分:可通过
onNodeWithTag("circularProgress")定位;两种指示器 Semantics 角色均为ProgressBar,需用 Tag 或额外属性区分
常见错误: 将
progress 传入 Float.NaN 或超出 [0,1] 范围会导致异常。始终确保在确定模式下 progress 的值在 0f..1f 之间。
// ❌ 错误:进度值越界
CircularProgressIndicator(progress = 1.5f) // 运行时崩溃
// ✅ 正确:使用 clamp 或业务逻辑约束
CircularProgressIndicator(progress = currentValue.coerceIn(0f, 1f))
2.4 通过 Semantics 树识别进度组件
测试框架通过 Composable 的 Semantics 属性感知进度指示器。两个组件自动附加以下关键属性:
| 属性 | 含义 | 测试 API |
|---|---|---|
Role.ProgressBar | 标识为进度条角色 | hasProgressBarRole() |
ProgressBarRangeInfo | 包含 current (当前值) 和 range (范围) | assert(ProgressBarRangeInfo) |
TestTag | 通过 Modifier.testTag 注入的唯一标识 | onNodeWithTag("tag") |
ContentDescription | 无障碍描述(可选) | onNodeWithContentDescription("加载中") |
调试技巧: 在测试中使用
composeTestRule.onRoot().printToLog("PROGRESS") 打印完整 Semantics 树,查看进度指示器的真实属性值。
2.5 性能与稳定性优化提示
- 避免在 Compose 中频繁触发 recomposition: 进度值更新应使用
derivedStateOf或snapshotFlow过滤高频变化,防止测试中超时。 - 测试中等待进度: 使用
composeTestRule.waitForIdle()或waitUntil等待进度值稳定。 - 异步更新进度: 协程中的进度更新应挂起于
Dispatchers.Main,测试时可通过runTest+advanceUntilIdle()控制时间。
关键总结: 两个组件在 Semantics 树中共享
ProgressBar 角色,通过 Modifier.testTag() 和 progress 值可唯一识别。测试时注意不确定模式(progress=null)下 ProgressBarRangeInfo 的 current 为 null,应单独判断。