Flutter截取TextField出现No MaterialLocalizations found错误
报错原因
No MaterialLocalizations found报错的核心原因是ScreenshotController.captureFromWidget()会在独立的离屏环境渲染传入的组件,这个环境默认不会继承你应用根节点MaterialApp提供的MaterialLocalizations依赖:
TextField是Material体系组件,渲染过程强依赖MaterialLocalizations提供的语义、交互提示、文本布局相关配置,仅用Material组件包裹无法满足依赖要求- 基础
Text组件不依赖Material本地化能力,所以替换后截图功能可以正常运行 - 你当前的代码还有一个隐藏问题:截图回调里直接调用
_buildTextField()会生成全新的TextField实例,不会携带用户已经输入的内容,就算解决报错也截不到用户实际输入的文本。
修复方案
分两步处理:
- 给离屏渲染的组件补全Material运行环境,解决本地化依赖缺失问题
- 同步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
相关产品推荐
相关产品推荐

