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

Flutter截取TextField出现No MaterialLocalizations found错误

报错原因

No MaterialLocalizations found报错的核心原因是ScreenshotController.captureFromWidget()会在独立的离屏环境渲染传入的组件,这个环境默认不会继承你应用根节点MaterialApp提供的MaterialLocalizations依赖:

  • TextField是Material体系组件,渲染过程强依赖MaterialLocalizations提供的语义、交互提示、文本布局相关配置,仅用Material组件包裹无法满足依赖要求
  • 基础Text组件不依赖Material本地化能力,所以替换后截图功能可以正常运行
  • 你当前的代码还有一个隐藏问题:截图回调里直接调用_buildTextField()会生成全新的TextField实例,不会携带用户已经输入的内容,就算解决报错也截不到用户实际输入的文本。
修复方案

分两步处理:

  1. 给离屏渲染的组件补全Material运行环境,解决本地化依赖缺失问题
  2. 同步TextField的实时输入内容,保证截图和用户实际看到的内容一致

修改后的完整可运行代码:

class TextFromUserState extends State<TextFromUser> {
  Uint8List? bytes;
  // 绑定TextField的文本控制器,用于获取用户实时输入
  final TextEditingController _inputController = TextEditingController();

  Widget _buildTextField({String? initialText}) {
    return Material(
      child: Container(
        child: TextField(
          // 页面正常渲染时用全局控制器,离屏截图时传入用户已输入的文本
          controller: initialText != null 
              ? TextEditingController(text: initialText) 
              : _inputController,
          decoration: InputDecoration(
            fillColor: Colors.grey[300],
            filled: true,
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _inputController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Read User input")),
      body: Column(
        children: <Widget>[
          _buildTextField(),
          if (bytes != null) Image.memory(bytes!),
        ],
      ),
      floatingActionButton: FloatingActionButton.extended(
        icon: const Icon(Icons.camera_alt),
        label: const Text('Capture'),
        onPressed: () async {
          final screenshotController = ScreenshotController();
          // 用MaterialApp包裹待截图组件,提供完整的Material环境依赖
          final capturedBytes = await screenshotController.captureFromWidget(
            MaterialApp(
              debugShowCheckedModeBanner: false,
              // 保持和主应用一致的主题配置,避免截图样式偏差
              theme: ThemeData.light(),
              localizationsDelegates: const [
                DefaultMaterialLocalizations.delegate,
                DefaultWidgetsLocalizations.delegate,
              ],
              home: Scaffold(
                body: _buildTextField(initialText: _inputController.text),
              ),
            ),
          );
          setState(() => bytes = capturedBytes);
        },
      ),
    );
  }
}

补充说明

  • 如果你的应用配置了多语言,把对应的本地化委托也添加到localizationsDelegates列表中即可
  • 如果不需要截取用户输入的内容,只需要截取空白TextField,可以去掉文本控制器相关逻辑,仅保留MaterialApp包裹待截图组件的部分就能解决报错
  • 包裹的MaterialApp建议配置和主应用完全一致的主题、本地化参数,避免截图效果和页面实际显示效果出现差异。

内容的提问来源于stack exchange,提问作者Salahuddin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 23:51:25