Android自定义EditText实现括号补全触发IndexOutOfBoundsException求助
问题根因分析
- 时序冲突:
afterTextChanged回调执行时,EditText的文本测量渲染流程还未完成,你在回调内直接删除字符、修改光标位置,会和正在执行的渲染流程产生状态不同步。刚启动时初始文本渲染处于冷启动状态,这个冲突会直接触发越界异常;而移动过光标后渲染状态已经完成过一轮更新,冲突不会触发。 - 边界判断缺失:你在取
editable.subSequence(start, start + count)前只判断了editable.length() > start,没有判断start + count <= editable.length(),初始位置插入时count值为3(插入的「[☢]」共3个字符),极端场景下会出现下标越界。 - 变量状态不匹配:
onTextChanged里存储的start和count可能和afterTextChanged里的editable实际状态不一致,首次冷启动输入时这个问题更容易触发。
修复方案
推荐直接替换原有占位符实现逻辑,代码更简洁也不会产生渲染冲突,修改后的MyEditText代码如下:
public class MyEditText extends AppCompatEditText { private final TextWatcher bracketWatcher = new TextWatcher() { // 标记位避免插入右括号时触发递归回调 private boolean isAppendingBracket = false; @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (isAppendingBracket || count != 1) return; // 检测到输入左括号时直接补全右括号 if (s.charAt(start) == '[') { isAppendingBracket = true; getText().insert(start + 1, "]"); // 光标定位到两个括号中间 setSelection(start + 1); isAppendingBracket = false; } } @Override public void afterTextChanged(Editable s) {} }; private void init() { addTextChangedListener(bracketWatcher); } public MyEditText(Context context) { super(context); init(); } public MyEditText(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } }
如果你希望保留原有占位符的实现逻辑,仅需要给afterTextChanged的操作加边界校验,并把修改操作post到主线程消息队列尾部,等渲染流程完成后再执行即可,修改后的afterTextChanged代码如下:
@Override public void afterTextChanged(Editable editable) { // 增加完整的边界校验 if (count > 1 && start >=0 && (start + count) <= editable.length()) { CharSequence newText = editable.subSequence(start, start + count); int i = newText.toString().indexOf(CURSOR); if (i > -1) { // 延迟到当前渲染任务完成后再执行修改 post(() -> { editable.delete(start + i, start + i + 1); setSelection(start + 1); }); } } }
内容的提问来源于stack exchange,提问作者Abdo21
相关产品推荐
相关产品推荐

