Compose 可访问性指南 — 构建 a11y-Ready UI
Source: Dev.to
Introduction
可访问性不是可选项。Jetpack Compose 提供了强大的工具来构建包容性的界面。
Code examples
Image(
painter = painterResource(R.drawable.ic_profile),
contentDescription = "User profile picture"
)
Icon(
imageVector = Icons.Filled.Check,
contentDescription = "Task completed"
)
规则:每个非装饰性的图像都需要描述。
Text(
text = "Settings",
modifier = Modifier.semantics {
heading()
}
)
Button(
onClick = { },
modifier = Modifier.semantics {
role = Role.Button
stateDescription = "Enabled"
}
) {
Text("Submit")
}
Card(
modifier = Modifier.semantics(mergeDescendants = true) {
contentDescription = "User card: Alice, 5 followers"
}
) {
Column {
Text("Alice")
Text("5 followers")
}
}
屏幕阅读器会读取合并后的描述,而不是每个子项。
Button(
modifier = Modifier.semantics {
customActions = listOf(
CustomAccessibilityAction("Swipe left to delete") { true }
)
},
onClick = { }
) {
Text("Delete")
}
为基于手势的交互提供键盘替代方案。
Text(
text = "Loading: $progress%",
modifier = Modifier.semantics {
liveRegion = LiveRegionMode.Assertive
}
)
向屏幕阅读器宣布变化。
Button(
modifier = Modifier.size(48.dp),
onClick = { }
) {
Text("Tap")
}
触控目标最小为 48 dp(WCAG 2.1)。
TextField(
value = email,
onValueChange = { email = it },
label = { Text("Email") },
modifier = Modifier.semantics {
contentDescription = "Email address required"
error = if (email.isEmpty()) "Email cannot be empty" else null
}
)
为表单验证加入错误语义。
Checklist
- ✓ 每个图像都有
contentDescription - ✓ 使用
semantics { heading() }标记标题 - ✓ 卡片使用
mergeDescendants = true - ✓ 最小 48 dp 触控目标
- ✓ 动态更新使用
liveRegion - ✓ 表单包含错误语义
- ✓ 使用 TalkBack(Android)或 VoiceOver(iOS)进行测试
Conclusion
可访问性惠及所有人:更好的屏幕阅读器支持、更清晰的语义以及更佳的可用性。从一开始就以包容的方式构建。
对移动应用开发感兴趣吗?在 Gumroad 上查看 8 套 Android 应用模板!