Flutter中如何避免EditableText光标失去焦点后跳至字符串末尾
问题:自定义按钮输入时EditableText光标跳至末尾
场景与代码
在Flutter应用中使用EditableText组件并禁用键盘输入,通过两个TextButton点击来修改绑定的TextEditingController文本内容:
EditableText代码
EditableText( keyboardType: TextInputType.none, autofocus: true, controller: _queryCtl, cursorColor: Colors.white, backgroundCursorColor: Colors.black, focusNode: tN, onTapOutside: (event) { print("tapped outside"); }, style: const TextStyle( fontSize: 32, color: Color.fromARGB(255, 219, 175, 42), ), )
自定义按钮代码
Row( children: [ TextButton( onPressed: () { addChar("2"); }, child: const Text('Add 2'), ), TextButton( onPressed: () { addChar("3"); }, child: const Text('Add 3'), ), ], )
问题现象
- 将光标放置在EditableText的字符串中间位置
- 首次点击TextButton,字符会插入到光标位置(符合预期)
- 再次点击TextButton,字符直接插入到字符串末尾(不符合预期)
解决方案
问题根源在于直接修改TextEditingController的text属性时,会自动重置光标位置到文本末尾。正确的做法是通过TextEditingValue同时更新文本和光标选中状态:
修改addChar方法如下:
void addChar(String char) { final currentValue = _queryCtl.value; final selection = currentValue.selection; // 构建新文本:在光标选中区域插入字符 final newText = currentValue.text.replaceRange( selection.start, selection.end, char, ); // 计算新的光标位置:插入位置 + 字符长度 final newSelection = selection.copyWith( baseOffset: selection.start + char.length, extentOffset: selection.start + char.length, ); // 更新controller的完整值,保留光标状态 _queryCtl.value = TextEditingValue( text: newText, selection: newSelection, composing: TextRange.empty, ); }
说明
- 避免直接使用
_queryCtl.text = ...或_queryCtl.text += ...这类方式修改文本,这类操作会丢失当前的光标选中状态 - 通过
TextEditingValue同时设置text和selection,可以确保光标始终停留在插入后的位置,模拟原生键盘的输入行为
内容的提问来源于stack exchange,提问作者Tanish
相关产品推荐
相关产品推荐

