如何在Flutter中为富文本编辑器创建自定义工具栏?
Flutter 富文本编辑器自定义工具栏实现方案
一、优先用 flutter_quill 实现自定义工具栏
flutter_quill 本身支持高度自定义,你之前没成功大概率是没用到正确的配置方式,以下是具体步骤:
1. 添加依赖
在 pubspec.yaml 中引入最新版依赖:
dependencies: flutter_quill: ^latest_version
2. 自定义工具栏组件
放弃默认的 QuillToolbar,自己构建布局并绑定 QuillController 实现功能:
class CustomQuillToolbar extends StatelessWidget { final QuillController controller; const CustomQuillToolbar({super.key, required this.controller}); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey.shade200)), ), child: Wrap( spacing: 8, runSpacing: 8, children: [ // 加粗按钮 IconButton( icon: const Icon(Icons.format_bold), onPressed: () => controller.formatSelection(Attribute.bold), ), // 斜体按钮 IconButton( icon: const Icon(Icons.format_italic), onPressed: () => controller.formatSelection(Attribute.italic), ), // 标题选择器 DropdownButton<String>( value: '正文', items: const [ DropdownMenuItem(value: '正文', child: Text('正文')), DropdownMenuItem(value: 'h1', child: Text('标题1')), DropdownMenuItem(value: 'h2', child: Text('标题2')), ], onChanged: (value) { if (value == 'h1') { controller.formatSelection(const Attribute.header(1)); } else if (value == 'h2') { controller.formatSelection(const Attribute.header(2)); } else { controller.formatSelection(const Attribute.header(0)); } }, ), // 有序列表 IconButton( icon: const Icon(Icons.format_list_numbered), onPressed: () => controller.formatSelection(const Attribute.list(Attribute.listOrdered)), ), // 无序列表 IconButton( icon: const Icon(Icons.format_list_bulleted), onPressed: () => controller.formatSelection(const Attribute.list(Attribute.listUnordered)), ), // 插入图片(需自行实现图片选择逻辑) IconButton( icon: const Icon(Icons.image), onPressed: () async { // 示例:调用图片选择器后插入 // final imagePath = await ImagePicker().pickImage(source: ImageSource.gallery); // if (imagePath != null) controller.insertImage(imagePath.path); }, ), // 可按需添加更多自定义按钮 ], ), ); } }
3. 组合工具栏与编辑器
在页面中关联自定义工具栏和 QuillEditor:
class RichTextEditorPage extends StatefulWidget { const RichTextEditorPage({super.key}); @override State<RichTextEditorPage> createState() => _RichTextEditorPageState(); } class _RichTextEditorPageState extends State<RichTextEditorPage> { final QuillController _controller = QuillController.basic(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('自定义富文本编辑器')), body: Column( children: [ CustomQuillToolbar(controller: _controller), Expanded( child: QuillEditor( controller: _controller, readOnly: false, autoFocus: false, scrollable: true, focusNode: FocusNode(), padding: const EdgeInsets.all(16), ), ), ], ), ); } }
二、其他包的自定义思路(若需尝试)
1. html_editor_enhanced
利用 customToolbar 参数传入自定义按钮,通过控制器执行命令:
HtmlEditor( controller: _htmlController, customToolbar: [ IconButton( icon: const Icon(Icons.format_bold), onPressed: () => _htmlController.executeCommand('bold'), ), // 其他按钮同理配置 ], )
2. quill_html_editor
通过 toolbarActions 参数配置自定义工具栏按钮:
QuillHtmlEditor( controller: _quillHtmlController, toolbarActions: [ ToolbarAction( icon: Icons.format_bold, onTap: () => _quillHtmlController.formatText('bold'), ), // 更多按钮配置 ], )
三、关键注意点
- 不同编辑器的控制器API不同,需对应调用(比如flutter_quill用
formatSelection,HTML类编辑器用executeCommand) - 可根据目标布局调整Wrap、Row、Column的组合,实现按钮分组、换行等样式
- 插入自定义内容(如表情、模板)可调用控制器的
insertText或insertEmbed方法
内容的提问来源于stack exchange,提问作者user14805610
相关产品推荐
相关产品推荐

