诡异Bug:输入框删除字符,却越删越多

最近在开发一个 Android 设备信息采集应用时,测试人员反馈了一个非常诡异的问题:在设备信息录入页面的一个文本输入框中,点击删除键非但无法删除字符,输入框内的文本反而越删越多,甚至出现重复拼接的现象。更让人头疼的是,这个问题只在英文语言环境下出现,且只在某个特定品牌的定制输入法上复现,换成系统默认输入法后一切正常。

经过排查与尝试,最终找到了根本原因并成功修复。

问题现象

  1. 用户在输入框中输入一段字符串(例如 SN2024001)。

  2. 点击删除键(Backspace),光标位置似乎正常,但文本长度非但没有减少,反而突然增长,甚至出现字符串重复。

  3. 继续点击删除键,文本持续异常增长,根本无法正常删除。

  4. 切换至系统默认输入法(如 Android 键盘 AOSP)后,删除功能恢复正常。

  5. 问题仅在英文语言环境下出现,中文环境正常;仅在某品牌定制输入法上复现,其他第三方输入法正常。

第一反应是怀疑自己的 TextWatcherRecyclerView 适配器存在 bug。反复检查代码:

  • TextWatcher.afterTextChanged() 中虽然更新了数据模型,但没有对文本进行任何二次修改。

  • 适配器中存在 notifyDataSetChanged() 调用,可能导致列表刷新时重新绑定了 EditText 内容。但即使改为 notifyItemChanged() 局部刷新,问题依旧。

  • 尝试添加编辑保护标志、焦点判断等方式,均无效。

让测试人员切换到系统默认输入法(AOSP),问题消失;

核心思路

  1. 强制禁用输入法联想 :通过 setInputType 增加 TYPE_TEXT_FLAG_NO_SUGGESTIONSTYPE_TEXT_VARIATION_VISIBLE_PASSWORD(密码类型会强制禁用联想,但字符仍正常显示)。

  2. 拦截删除键事件 :为 EditText 设置 OnKeyListener,当检测到 KEYCODE_DEL 时,手动删除最后一个字符,并返回 true 表示事件已消费。

  3. 清理可能干扰的配置 :清空 setPrivateImeOptions,防止旧配置影响。

代码实现

在列表适配器的 onBindViewHolder

java 复制代码
// 强制输入类型,禁用联想
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);

// 增加密码类型标记(仅影响输入法行为,界面仍是明文)
editText.setInputType(editText.getInputType() | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);

// 清空私有参数
editText.setPrivateImeOptions("");

// 应用层接管删除键
editText.setOnKeyListener((v, keyCode, event) -> {
    if (keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) {
        Editable text = ((EditText) v).getText();
        if (text != null && text.length() > 0) {
            // 删除最后一个字符
            text.delete(text.length() - 1, text.length());
        }
        return true; // 事件已处理,不再交给输入法
    }
    return false;
});

同时在布局文件中editText添加下面的设置:

XML 复制代码
android:inputType="textNoSuggestions"
android:importantForAutofill="no"
android:autofillHints=""

测试ok.

相关推荐
执明wa15 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio
404_coder16 小时前
源码视角下的 Android 开机流程:从 Zygote、SystemServer 到 Launcher
android
二流小码农16 小时前
鸿蒙开发:以登录案例了解代码架构MVVM
android·ios·harmonyos
用户693717500138417 小时前
从代码生产者到 AI 协作者:软件工程师的角色重构
android·前端·后端
GitLqr17 小时前
别在 Flutter 的 main() 里乱锁屏幕方向,小心 iPad 分屏功能被你搞没了
android·flutter·ios
sg_knight17 小时前
MySQL 存储过程详解:从入门到实战
android·数据库·mysql·database·dba·关系型数据库·db
爱笑鱼17 小时前
Binder(四):ioctl(BINDER_WRITE_READ) 之后,事务怎样到达目标进程?
android
AFinalStone17 小时前
Android 7系统休眠唤醒(二)开机全链路—BootROM到Launcher
android·电源管理·休眠唤醒
Mr YiRan17 小时前
Android NDK开发之统计到未被回收的图片
android