You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose无障碍表单验证:让Talkback读取自定义错误信息的方案

Jetpack Compose 无障碍表单验证优化方案

一、解决默认错误提示覆盖自定义信息的问题

OutlinedTextField设置isError = true后,会自动添加默认的"error, invalid input"语义,导致自定义错误信息被掩盖。通过自定义语义可以完全替换这一默认行为:

OutlinedTextField(
    value = viewModel.emailValue,
    onValueChange = viewModel::updateEmail,
    label = { Text("邮箱") },
    isError = viewModel.emailError != null,
    modifier = Modifier.semantics {
        // 传入自定义错误信息,替换默认提示
        viewModel.emailError?.let { error(it) }
        // 关闭默认的"invalid input"提示
        this[Error] = false
    }
)

// 显示错误文本(保持可见,供视觉用户查看)
viewModel.emailError?.let {
    Text(
        text = it,
        color = MaterialTheme.colorScheme.error,
        style = MaterialTheme.typography.bodySmall,
        modifier = Modifier.padding(start = 16.dp, top = 4.dp)
    )
}

此时聚焦文本框时,Talkback会直接读取自定义错误信息,不再附带默认提示。

二、提交时主动播报所有表单错误

点击提交按钮后,通过announceForAccessibility主动触发错误汇总播报,确保用户能一次性获取所有问题:

1. ViewModel中统一收集错误信息

class FormViewModel : ViewModel() {
    var emailValue by mutableStateOf("")
    var passwordValue by mutableStateOf("")
    var emailError by mutableStateOf<String?>(null)
    var passwordError by mutableStateOf<String?>(null)

    fun validateForm(): List<String> {
        val errors = mutableListOf<String>()
        if (!emailValue.matches(Regex("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$"))) {
            emailError = "请输入有效的邮箱地址"
            errors.add(emailError!!)
        } else {
            emailError = null
        }
        if (passwordValue.length < 6) {
            passwordError = "密码长度不能少于6位"
            errors.add(passwordError!!)
        } else {
            passwordError = null
        }
        return errors
    }
}

2. 提交按钮中触发播报逻辑

val viewModel: FormViewModel = viewModel()
val localView = LocalView.current

Button(
    onClick = {
        val errors = viewModel.validateForm()
        if (errors.isNotEmpty()) {
            // 拼接所有错误,用自然语言分隔
            val errorSummary = errors.joinToString(",")
            // 主动通知Talkback播报错误汇总
            localView.announceForAccessibility(errorSummary)
        } else {
            // 执行表单提交逻辑
        }
    }
) {
    Text("提交")
}

三、额外无障碍优化建议

  • 实时验证用LiveRegion自动播报:如果字段支持输入时即时验证(比如输完邮箱立刻提示格式错误),可以用LiveRegion包裹错误文本,确保错误出现时自动被播报:
    LiveRegion(liveRegionMode = LiveRegionMode.Assertive) {
        viewModel.emailError?.let {
            Text(text = it, color = MaterialTheme.colorScheme.error)
        }
    }
    
  • 保持错误文本可见:视觉错误提示和无障碍语义要保持一致,不要隐藏错误文本,同时兼顾视觉用户和无障碍用户的需求。
  • 避免重复播报:如果已经通过announceForAccessibility汇总播报了所有错误,无需再让每个文本框单独播报,减少信息冗余。

内容的提问来源于stack exchange,提问作者Tobias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 17:30:12