You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 10:12:03