安卓onTextChanged()行为不一致 输入3位以上数字后回调参数异常
回答
首先明确TextWatcher#onTextChanged方法的官方参数定义:
fun onTextChanged( s: CharSequence?, // 变更后的完整文本内容 start: Int, // 本次变更发生的起始索引 before: Int, // 本次变更中被替换掉的旧文本长度 count: Int // 本次变更中新增的新文本长度 )
你观察到的所有现象都不是系统或TextWatcher的bug,完全是输入法的自主行为导致的,具体原因如下:
- 纯字母输入时的全量替换回调
你认为"符合预期"的每次start=0、before等于旧文本长度、count等于新文本长度的情况,是当前使用的输入法默认开启了全量文本提交模式。这种模式下每次输入新字符,输入法会直接把输入框的全部内容替换成添加新字符后的完整文本,所以回调的变更范围覆盖整个文本,通常是输入法为了支持联想输入、拼写校验随时修改前文内容而设计的。 - 输入3位数字后的无变更回调
你标注的异常点(文本内容没有变化、before=8、count=8),是输入法检测到连续3位数字后,触发了数字序列格式化预校验逻辑(比如判断是不是电话号码、银行卡号,要不要自动添加空格分隔符),最终判断不需要修改文本,所以提交了一次无内容变化的替换回调:把位置0开始长度为8的文本,替换成同样长度的相同内容,就出现了before和count相等、文本不变的情况。 - 后续输入字母的增量回调
输入完3位数字后再输入字母时,输入法判断当前输入是数字+字母的混合序列,不属于可格式化的纯数字内容,所以自动切换为增量提交模式:每次输入新字符仅在文本末尾追加,不会替换整个文本,所以回调的start是当前文本的末尾索引、before=0(没有旧内容被替换)、count=1(仅新增1个字符)。
验证方案
关闭输入法的自动联想、拼写检查、数字自动格式化功能,或者切换到系统自带的无联想输入法重新测试,就不会出现回调逻辑切换的现象。
内容的提问来源于stack exchange,提问作者Vsevolod IV
相关产品推荐
相关产品推荐

