Flutter富文本编辑器插件quill_html_editor的使用
Flutter富文本编辑器插件quill_html_editor的使用
插件介绍
Quill Html Editor 是一个强大的HTML富文本编辑器,适用于Android、iOS和Web平台。它利用了QuillJs库的功能,为现代Web应用程序提供丰富的编辑体验。
功能特性
- 高度自定义:支持自定义
Editor
和Toolbar
小部件。 - Delta格式支持:允许使用
setDelta
和getDelta
方法设置和获取内容。 - 无缝复制粘贴:支持从其他文件或网页中无缝复制粘贴富文本。
- 灵活的工具栏位置:工具栏可以放置在页面的任何位置。
- 自定义按钮:支持添加自定义按钮到工具栏。
- 多媒体嵌入:支持嵌入图片、视频以及插入表格。
- 多格式支持:允许以HTML和Delta格式设置和获取文本。
- Google Fonts集成:支持与Google Fonts集成,提供更多字体选项。
示例代码
项目初始化
import 'package:flutter/material.dart';
import 'package:quill_html_editor/quill_html_editor.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MaterialApp(debugShowCheckedModeBanner: false, home: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late QuillEditorController controller;
final customToolBarList = [
ToolBarStyle.bold,
ToolBarStyle.italic,
ToolBarStyle.align,
ToolBarStyle.color,
ToolBarStyle.background,
ToolBarStyle.listBullet,
ToolBarStyle.listOrdered,
ToolBarStyle.clean,
ToolBarStyle.addTable,
ToolBarStyle.editTable,
];
final _toolbarColor = Colors.grey.shade200;
final _backgroundColor = Colors.white70;
final _toolbarIconColor = Colors.black87;
final _editorTextStyle = const TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.normal,
fontFamily: 'Roboto');
final _hintTextStyle = const TextStyle(
fontSize: 18, color: Colors.black38, fontWeight: FontWeight.normal);
bool _hasFocus = false;
@override
void initState() {
controller = QuillEditorController();
controller.onTextChanged((text) {
debugPrint('listening to $text');
});
controller.onEditorLoaded(() {
debugPrint('Editor Loaded :)');
});
super.initState();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomInset: true,
body: Column(
children: [
// 工具栏配置
ToolBar(
toolBarColor: _toolbarColor,
padding: const EdgeInsets.all(8),
iconSize: 25,
iconColor: _toolbarIconColor,
activeIconColor: Colors.greenAccent.shade400,
controller: controller,
crossAxisAlignment: WrapCrossAlignment.start,
direction: Axis.horizontal,
customButtons: [
Container(
width: 25,
height: 25,
decoration: BoxDecoration(
color: _hasFocus ? Colors.green : Colors.grey,
borderRadius: BorderRadius.circular(15)),
),
InkWell(
onTap: () => unFocusEditor(),
child: const Icon(
Icons.favorite,
color: Colors.black,
)),
InkWell(
onTap: () async {
var selectedText = await controller.getSelectedText();
debugPrint('selectedText $selectedText');
var selectedHtmlText =
await controller.getSelectedHtmlText();
debugPrint('selectedHtmlText $selectedHtmlText');
},
child: const Icon(
Icons.add_circle,
color: Colors.black,
)),
],
),
// 编辑器配置
Expanded(
child: QuillHtmlEditor(
text: "<h1>Hello</h1>This is a quill html editor example 😊",
hintText: 'Hint text goes here',
controller: controller,
isEnabled: true,
ensureVisible: false,
minHeight: 500,
autoFocus: false,
textStyle: _editorTextStyle,
hintTextStyle: _hintTextStyle,
hintTextAlign: TextAlign.start,
padding: const EdgeInsets.only(left: 10, top: 10),
hintTextPadding: const EdgeInsets.only(left: 20),
backgroundColor: _backgroundColor,
inputAction: InputAction.newline,
onEditingComplete: (s) => debugPrint('Editing completed $s'),
loadingBuilder: (context) {
return const Center(
child: CircularProgressIndicator(
strokeWidth: 1,
color: Colors.red,
));
},
onFocusChanged: (focus) {
debugPrint('has focus $focus');
setState(() {
_hasFocus = focus;
});
},
onTextChanged: (text) => debugPrint('widget text change $text'),
onEditorCreated: () {
debugPrint('Editor has been loaded');
setHtmlText('Testing text on load');
},
onEditorResized: (height) =>
debugPrint('Editor resized $height'),
onSelectionChanged: (sel) =>
debugPrint('index ${sel.index}, range ${sel.length}'),
),
),
],
),
bottomNavigationBar: Container(
width: double.maxFinite,
color: _toolbarColor,
padding: const EdgeInsets.all(8),
child: Wrap(
children: [
textButton(
text: 'Set Text',
onPressed: () {
setHtmlText('This text is set by you 🫵');
}),
textButton(
text: 'Get Text',
onPressed: () {
getHtmlText();
}),
textButton(
text: 'Insert Video',
onPressed: () {
insertVideoURL(
'https://www.youtube.com/watch?v=4AoFA19gbLo');
insertVideoURL('https://vimeo.com/440421754');
insertVideoURL(
'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4');
}),
textButton(
text: 'Insert Image',
onPressed: () {
insertNetworkImage('https://i.imgur.com/0DVAOec.gif');
}),
textButton(
text: 'Insert Index',
onPressed: () {
insertHtmlText("This text is set by the insertText method",
index: 10);
}),
textButton(
text: 'Undo',
onPressed: () {
controller.undo();
}),
textButton(
text: 'Redo',
onPressed: () {
controller.redo();
}),
textButton(
text: 'Clear History',
onPressed: () async {
controller.clearHistory();
}),
textButton(
text: 'Clear Editor',
onPressed: () {
controller.clear();
}),
textButton(
text: 'Get Delta',
onPressed: () async {
var delta = await controller.getDelta();
debugPrint('delta');
debugPrint(jsonEncode(delta));
}),
textButton(
text: 'Set Delta',
onPressed: () {
final Map<dynamic, dynamic> deltaMap = {
"ops": [
{
"insert": {
"video":
"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
}
},
{
"insert": {
"video": "https://www.youtube.com/embed/4AoFA19gbLo"
}
},
{"insert": "Hello"},
{
"attributes": {"header": 1},
"insert": "\n"
},
{"insert": "You just set the Delta text 😊\n"}
]
};
controller.setDelta(deltaMap);
}),
],
),
),
),
);
}
Widget textButton({required String text, required VoidCallback onPressed}) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: MaterialButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
color: _toolbarIconColor,
onPressed: onPressed,
child: Text(
text,
style: TextStyle(color: _toolbarColor),
)),
);
}
void getHtmlText() async {
String? htmlText = await controller.getText();
debugPrint(htmlText);
}
void setHtmlText(String text) async {
await controller.setText(text);
}
void insertNetworkImage(String url) async {
await controller.embedImage(url);
}
void insertVideoURL(String url) async {
await controller.embedVideo(url);
}
void insertHtmlText(String text, {int? index}) async {
await controller.insertText(text, index: index);
}
void clearEditor() => controller.clear();
void enableEditor(bool enable) => controller.enableEditor(enable);
void unFocusEditor() => controller.unFocus();
}
关键功能说明
- QuillEditorController:用于访问编辑器的方法。
- ToolBar:工具栏组件,支持自定义按钮和样式。
- QuillHtmlEditor:编辑器组件,支持多种事件回调和属性配置。
- Custom Buttons:可以通过
customButtons
参数添加自定义按钮。 - Custom Fonts:通过
TextStyle
中的fontFamily
属性指定自定义字体。
其他功能
-
获取HTML字符串:
String? htmlText = await controller.getText();
-
设置HTML字符串:
await controller.setText(text);
-
获取Delta格式:
await controller.getDelta();
-
设置Delta格式:
controller.setDelta(deltaMap);
-
插入HTML字符串:
await controller.insertText(text, index: 10);
-
清空编辑器:
controller.clear();
-
启用/禁用编辑器:
controller.enableEditor(true); // 启用 controller.enableEditor(false); // 禁用
待办事项
- CustomStyleButton:让用户添加自己的图标到工具栏样式。
- Custom Color:让用户添加更多颜色到颜色选择器。
- Custom FontSize:让用户添加自定义字体大小。
- AsyncImagePickerButton:异步上传并插入返回的链接到编辑器。
- 提供每个可用API的更多示例。
许可证
MIT License
Copyright © 2022 Pavan Kumar Nagulavancha
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
以上是关于quill_html_editor
插件的详细介绍和示例代码,希望对您有所帮助!如果有任何问题或需要进一步的帮助,请随时联系我。
更多关于Flutter富文本编辑器插件quill_html_editor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter富文本编辑器插件quill_html_editor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中集成和使用quill_html_editor
插件的示例代码。quill_html_editor
是一个基于Quill的富文本编辑器,它允许你在Flutter应用中实现HTML内容的编辑和显示。
1. 添加依赖
首先,你需要在pubspec.yaml
文件中添加quill_html_editor
依赖:
dependencies:
flutter:
sdk: flutter
quill_html_editor: ^x.y.z # 替换为最新版本号
运行flutter pub get
来安装依赖。
2. 导入包
在你的Dart文件中导入quill_html_editor
包:
import 'package:quill_html_editor/quill_html_editor.dart';
3. 使用QuillHtmlEditor
以下是一个简单的示例,展示了如何在Flutter应用中使用QuillHtmlEditor
:
import 'package:flutter/material.dart';
import 'package:quill_html_editor/quill_html_editor.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Quill HTML Editor Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final QuillController _quillController = QuillController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Quill HTML Editor Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: QuillHtmlEditor(
controller: _quillController,
placeholder: 'Start writing...',
readOnly: false, // 设置为true则只读
),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
// 获取HTML内容
String htmlContent = _quillController.toHtml();
print(htmlContent); // 打印HTML内容到控制台
// 如果你想在UI中显示HTML内容,可以使用`HtmlWidget`(需要`flutter_html`包)
// 注意:你需要先在`pubspec.yaml`中添加`flutter_html`依赖
// import 'package:flutter_html/flutter_html.dart';
// showDialog(
// context: context,
// builder: (BuildContext context) {
// return AlertDialog(
// title: Text('HTML Content'),
// content: SingleChildScrollView(
// child: HtmlWidget(htmlContent),
// ),
// );
// },
// );
},
child: Text('Get HTML Content'),
),
],
),
),
);
}
}
4. 注意事项
- 确保你已经添加了
quill_html_editor
依赖,并且运行了flutter pub get
。 - 如果你想在UI中显示HTML内容,可以使用
flutter_html
包,上面的代码示例中已经包含了注释说明。 - 你可以根据需要对
QuillHtmlEditor
进行更多配置,比如设置样式、工具栏按钮等。
这个示例展示了基本的集成和使用方法,你可以根据需要进一步扩展和定制。