在使用flutter的时候,正好使用到了TextField组件,然后有一个功能需要清空操作。
但在清空操作的时候,虽然可以正常清空,但是会报如下错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
════════ Exception caught by gesture ═══════════════════════════════════════════ The following assertion was thrown while handling a gesture: invalid text selection: TextSelection(baseOffset: 3, extentOffset: 3, affinity: TextAffinity.upstream, isDirectional: false) When the exception was thrown, this was the stack When the exception was thrown, this was the stack #0 TextEditingController.selection= package:flutter/…/widgets/editable_text.dart:193 #1 EditableTextState._handleSelectionChanged package:flutter/…/widgets/editable_text.dart:1379 #2 RenderEditable._handlePotentialSelectionChange package:flutter/…/rendering/editable.dart:388 #3 RenderEditable.selectPositionAt package:flutter/…/rendering/editable.dart:1487 #4 RenderEditable.selectPosition package:flutter/…/rendering/editable.dart:1459 ... Handler: "onTapUp" Recognizer: _TransparentTapGestureRecognizer#7fe65 debugOwner: _TextSelectionGestureDetectorState#4fb86 state: ready won arena finalPosition: Offset(319.6, 54.1) finalLocalPosition: Offset(303.6, 26.1) sent tap down ════════════════════════════════════════════════════════════════════════════════ |
关于此情况并大概就是在没有正常的取消输入框焦点的时候,就先清空输入框组件,整体渲染顺序是不正确的。
如下是我的错误代码(会报上面的错误代码):
我是直接调用controller取消输入框内容的方法,但是光标会聚集在此输入框,所以处理渲染生命周期是不可控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
class SearchInputText extends StatefulWidget { @override _SearchInputTextState createState() => _SearchInputTextState(); } class _SearchInputTextState extends State<SearchInputText> { TextEditingController controller = TextEditingController(); // 清空X按钮事件 onCancel() { controller.clear(); // 清空输入框内容 } @override Widget build(BuildContext context) { return Container( child: TextField( controller: controller, textInputAction: TextInputAction.search, decoration: InputDecoration( contentPadding: EdgeInsets.all(0.0), // 整体边距 hintText: 'search', hintStyle: TextStyle(color: Color.fromRGBO(192, 192, 192, 0.8)), // 右侧第二个图标,只有移入光标才会显示 suffix: IconButton( icon: Icon(Icons.close), onPressed: onCancel, ), ), ), ); } } |
既然知道报错的大概方向,那么我们就控制build的生命周期插入指定时机才去运行方法即可
onCancel函数方法改造如下,
1 2 3 4 |
onCancel() { // 保证在组件build的第一帧时才去触发取消清空内容 WidgetsBinding.instance.addPostFrameCallback((_) => controller.clear()); } |
在组件合适的机制处理后,就不会报错误了!