FlutterSummerNote的getText()方法首次点击保存按钮返回空值问题求助
问题原因
这个问题是flutter_summernote: ^1.0.0版本的原生逻辑缺陷,底层依赖的WebView加载富文本编辑器内核完成后,输入内容和JS侧的内容同步存在时序差:首次触发getText()时,JS侧还未将用户输入的内容同步到读取接口的返回值中,因此会拿到空值,第二次调用时同步已经完成,就能正常取值。
可行解决方案
方案1:添加初始化状态标记 + 短延迟兜底
通过组件提供的onLoaded回调标记编辑器是否初始化完成,调用getText()前添加极短的延迟等待内容同步,用户完全感知不到延迟,修改后的代码如下:
import 'package:flutter/material.dart'; import 'package:flutter_summernote/flutter_summernote.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Demo Flutter Summernote'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({required this.title}); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { GlobalKey<FlutterSummernoteState> _keyEditor = GlobalKey(); // 新增编辑器初始化完成标记 bool _isEditorLoaded = false; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), elevation: 0, actions: <Widget>[ IconButton( icon: Icon(Icons.save), // 未初始化完成时禁止点击,避免空值 onPressed: _isEditorLoaded ? () async { // 添加100毫秒延迟等待内容同步,可根据实际情况调整时长 await Future.delayed(const Duration(milliseconds: 100)); final value = await _keyEditor.currentState?.getText(); ScaffoldMessenger.of(context).showSnackBar(SnackBar( duration: Duration(seconds: 5), content: Text(value ?? "-"), )); } : null, ) ], ), backgroundColor: Colors.white, body: FlutterSummernote( hint: "Your text here...", key: _keyEditor, hasAttachment: true, // 新增onLoaded回调,标记初始化完成 onLoaded: () { setState(() { _isEditorLoaded = true; }); }, customToolbar: """ [ ['style', ['bold', 'italic', 'underline', 'clear']], ['font', ['strikethrough', 'superscript', 'subscript']], ['insert', ['link', 'table', 'hr']] ] """, ), ); } }
注意:如果需要给编辑器设置初始内容,建议在
onLoaded回调中调用_keyEditor.currentState?.setText("初始内容"),避免初始内容加载失败的问题。
方案2:二次读取兜底
如果不想控制按钮状态,也可以在首次拿到空值时自动重试一次读取,逻辑如下:
onPressed: () async { String? value = await _keyEditor.currentState?.getText(); // 首次为空则重试一次 if(value == null || value.isEmpty) { await Future.delayed(const Duration(milliseconds: 50)); value = await _keyEditor.currentState?.getText(); } ScaffoldMessenger.of(context).showSnackBar(SnackBar( duration: Duration(seconds: 5), content: Text(value ?? "-"), )); }
内容的提问来源于stack exchange,提问作者cris gomez
相关产品推荐
相关产品推荐

