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

如何为Jetpack Compose TextField实现常驻占位提示?修复光标跳转异常

M3 TextField 输入补全提示实现及光标异常修复

问题背景

M3的TextField组件默认placeholder仅在聚焦且输入为空时显示文本。需要实现类似Github Copilot的输入补全提示效果:用户输入过程中,始终在输入内容后显示灰色的补全后缀。目前视觉效果已实现,但光标移动逻辑异常,会跳到灰色提示文本末尾,问题出在OffsetMapping的映射逻辑上。

修正方案

核心是确保光标只能在用户实际输入的文本范围内移动,禁止进入补全后缀区域,修正OffsetMapping的两个映射方法:

  • originalToTransformed:原始输入的偏移量直接对应转换后文本的偏移量(用户输入内容在前,补全后缀在后,原始偏移量无需额外计算)
  • transformedToOriginal:若点击/移动的位置超过用户输入的长度,直接映射到输入内容的末尾,避免光标进入补全后缀区域

同时优化补全后缀的生成逻辑:仅当补全内容是用户输入的延续时才显示后缀,避免无关文本干扰。

修正后的代码

class MyMaskTransformation(
    private val suggestion: String
) : VisualTransformation {

    override fun filter(text: AnnotatedString): TransformedText {
        // 仅当suggestion是用户输入的延续时,生成补全后缀
        val suffix = if (suggestion.startsWith(text.toString()) && suggestion.length > text.length) {
            suggestion.substring(text.length)
        } else {
            ""
        }
        
        return TransformedText(
            offsetMapping = object : OffsetMapping {
                override fun originalToTransformed(offset: Int): Int {
                    // 原始输入偏移量直接对应转换后文本的位置
                    return offset
                }

                override fun transformedToOriginal(offset: Int): Int {
                    // 限制光标只能在用户输入的文本范围内,超过则定位到输入末尾
                    return min(offset, text.length)
                }
            },
            text = buildAnnotatedString {
                append(text)
                withStyle(SpanStyle(Color.Gray)) {
                    append(suffix)
                }
            }
        )
    }
}

关键优化点

  • 移除了全局suffix变量,改为在filter方法内计算,避免状态不一致问题
  • 增加补全有效性判断:只有当suggestion以用户输入内容开头时才显示后缀,确保补全提示的关联性
  • transformedToOriginal方法通过min(offset, text.length)强制限制光标范围,彻底解决光标跳转到后缀末尾的异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:52:55