Flutter桌面应用TextFormField粘贴文本时崩溃问题求助
Flutter桌面应用粘贴文本到TextFormField时随机崩溃
我开发的Flutter桌面应用,往TextFormField粘贴文本时有50%概率崩溃,调试控制台仅显示错误信息:Lost connection to device. Exited (sigterm),找不到相关问题排查方向,求帮助。
组件代码
Widget build(BuildContext context) { return Padding( padding: widget.padded ? const EdgeInsets.fromLTRB(13.0, 6.0, 13.0, 0.0) : const EdgeInsets.fromLTRB(2.0, 6.0, 2.0, 0.0), child: Row( children: [ Expanded( child: TextFormField( onChanged: widget.onTextChanged, decoration: InputDecoration( hintText: widget.hintText, isDense: true, contentPadding: const EdgeInsets.symmetric(horizontal: 13, vertical: 9), ), style: const TextStyle(fontSize: 11), maxLines: null, initialValue: widget.defaultText, expands: widget.expands, )) ], ), ); }
必崩溃的示例文本
* Name Sarah * Date 2022/10/05 * Topic Animals + Pets<Speaking> * New Language wildlife <noun>||animals, birds, and plants living in their natural environment fox <noun>||a wild animal like a dog with red-brown fur, a pointed nose, and a long, thick tail red panda <noun>||an animal with reddish-brown fur and a long bushy tail that lives mainly in trees, especially in China and Nepal owl <noun>||a bird with a flat face and large eyes that hunts small mammals at night swan <noun>||a large, usually white bird with a long neck that lives on rivers and lakes breed <noun>||to keep animals for the purpose of producing young animals in a controlled way * Pronunciation bear||be~r * Corrections Four day, we start running||On the fourth day, we started running in this trip||on this trip I meet a lot of new friends||I have met a lot of new friends There are many house made by wood ||... made of wood//i\The difference between 'made from', 'made of', and 'made by' can be tricky, so let me know if you need any help with them!\ I saw them in long distance||I saw them from far away//I saw them from a distance They are originally from Russian||... from Russia ===
onChanged回调代码
onChanged: ((value) { if (_textController.text.endsWith('\n')) { // Add the prefix everytime a new line is created _textController.text += _linePrefix; } _text = value; }),
问题根源及解决方案
核心问题
在onChanged里直接修改_textController.text会触发无限循环:
- 粘贴文本触发
onChanged - 修改控制器文本会再次触发
onChanged - 反复触发导致应用资源耗尽,最终因
sigterm崩溃
同时,TextFormField同时设置initialValue和外部控制器属于冲突配置,会加剧问题。
修复步骤
统一用控制器管理文本,移除
initialValue
初始化时将默认值直接赋值给控制器,不再给TextFormField传递initialValue参数。改用控制器监听替代
onChanged,避免循环触发
监听控制器文本变化,修改文本时先临时移除监听,完成后重新添加,防止无限循环:
@override void initState() { super.initState(); // 初始化控制器默认值 _textController.text = widget.defaultText; _textController.addListener(_handleTextChange); } @override void dispose() { _textController.removeListener(_handleTextChange); _textController.dispose(); super.dispose(); } void _handleTextChange() { final currentText = _textController.text; // 避免重复添加前缀,先做判断 if (currentText.endsWith('\n') && !currentText.endsWith('$_linePrefix\n')) { _textController.removeListener(_handleTextChange); _textController.text = currentText + _linePrefix; // 将光标定位到文本末尾 _textController.selection = TextSelection.fromPosition( TextPosition(offset: _textController.text.length), ); _textController.addListener(_handleTextChange); } _text = currentText; } // 修改TextFormField配置 TextFormField( controller: _textController, // 保留其他原有属性 )
- 测试验证
使用提供的示例文本进行粘贴测试,崩溃问题应该可以解决。
内容的提问来源于stack exchange,提问作者Michael Cullen
相关产品推荐
相关产品推荐

