TextField视觉转换报错:OffsetMapping.originalToTransformed返回无效映射
解决方案
错误原因
你遇到的offsetmapping.originaltotransformed returned invalid mapping错误,是因为原掩码逻辑在文本长度小于4时,生成的转换后文本长度(固定4个*)与原始文本长度不一致,而OffsetMapping.Identity要求原始和转换后的文本长度完全匹配,导致光标位置映射失效。
核心修复步骤
- 保证转换前后文本长度一致:掩码长度随原始文本动态调整,文本长度≤4时掩码全部字符,长度>4时仅掩码前4个字符,避免固定生成4个
*。 - 区分编辑/非编辑状态:通过状态变量控制掩码开关,用户开始编辑时自动关闭掩码。
完整代码实现
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.TextField import androidx.compose.runtime.* import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.input.OffsetMapping // 自定义用户名掩码转换 class UsernameMaskTransformation : VisualTransformation { override fun filter(text: AnnotatedString): TransformedText { return maskFilter(text) } } private fun maskFilter(text: AnnotatedString): TransformedText { // 动态计算掩码长度:最多4个,文本长度不足4时掩码全部字符 val maskCount = min(4, text.length) val maskedContent = "*".repeat(maskCount) + text.substring(maskCount) // 转换前后长度一致,直接用Identity映射即可 return TransformedText(AnnotatedString(maskedContent), OffsetMapping.Identity) } // 登录表单示例 @Composable fun LoginUsernameField() { // 用户名状态 var username by remember { mutableStateOf("") } // 编辑状态标记:true时关闭掩码 var isEditing by remember { mutableStateOf(false) } // 保存原始已存储的用户名(模拟从本地加载) val originalUsername by remember { mutableStateOf("johndoe") } // 初始化加载已保存的用户名 LaunchedEffect(Unit) { username = originalUsername isEditing = false } TextField( value = username, onValueChange = { input -> // 用户开始输入时切换到编辑状态,关闭掩码 if (!isEditing) { isEditing = true } username = input }, visualTransformation = if (isEditing) VisualTransformation.None else UsernameMaskTransformation(), label = { androidx.compose.material3.Text("用户名") }, onFocusChanged = { focusState -> // 失去焦点且未修改用户名时,恢复掩码显示 if (!focusState.isFocused && username == originalUsername) { isEditing = false } } ) }
逻辑说明
- 非编辑状态:显示已保存的用户名时,自动掩码前4个字符(文本长度≤4时全掩码),转换前后文本长度一致,光标映射不会出错。
- 编辑状态:用户首次输入字符时自动关闭掩码;若用户未修改用户名并失去焦点,会重新恢复掩码显示;若修改了用户名,则保持掩码关闭状态。
内容的提问来源于stack exchange,提问作者dchks11
相关产品推荐
相关产品推荐

