Flutter 文本编辑器使用
  w7nT9BWOuqag 2023年11月02日 92 0


最近项目里要用到图文编辑,于是寻找技术方案

在这儿,我也是找到了一个不错的插件,分享给大家,


介绍

Flutter HTML Editor Enhanced 是一款适用于 Android、iOS 和 Web 的文本编辑器,可帮助大家编写所见即所得的 HTML 代码。在线​​API 参考​

安装

方式一:运行此命令:

add

这将在你的包的 pubspec.yaml 中添加这样的一行(并运行一个隐式​​flutter pub get​​):

或者直接在pubspec.yaml 中添加之后,

dependencies:
html_editor_enhanced: ^2.5.0

运行

Flutter 文本编辑器使用_flutter

、或者,您的编辑器可能支持​​flutter pub get​​. 检查您的编辑器的文档以了解更多信息。

导入它

现在在您的 Dart 代码中,您可以使用:

import 'package:html_editor_enhanced/html_editor.dart';
import 'package:html_editor_enhanced/utils/callbacks.dart';
import 'package:html_editor_enhanced/utils/file_upload_model.dart';
import 'package:html_editor_enhanced/utils/options.dart';
import 'package:html_editor_enhanced/utils/plugins.dart';
import 'package:html_editor_enhanced/utils/shims/dart_ui.dart';
import 'package:html_editor_enhanced/utils/shims/dart_ui_fake.dart';
import 'package:html_editor_enhanced/utils/shims/dart_ui_real.dart';
import 'package:html_editor_enhanced/utils/shims/flutter_inappwebview_fake.dart';
import 'package:html_editor_enhanced/utils/toolbar.dart';
import 'package:html_editor_enhanced/utils/utils.dart';

最简单的使用

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:html_editor_enhanced/html_editor.dart';
import 'package:file_picker/file_picker.dart';

void main() => runApp(HtmlEditorExampleApp());

class HtmlEditorExampleApp extends StatelessWidget{
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(),
darkTheme: ThemeData.dark(),
home: HtmlEditorExample(title: '大前端之旅'),
);
}
}

class HtmlEditorExample extends StatefulWidget{
HtmlEditorExample({Key? key, required this.title}) : super(key: key);

final String title;

@override
_HtmlEditorExampleState createState() => _HtmlEditorExampleState();
}

class _HtmlEditorExampleState extends State<HtmlEditorExample> {
String result = '';
final HtmlEditorController controller = HtmlEditorController();

@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
if (!kIsWeb) {
controller.clearFocus();
}
},
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
elevation: 0,
actions: [
IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
if (kIsWeb) {
controller.reloadWeb();
} else {
controller.editorController!.reload();
}
})
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.toggleCodeView();
},
child: Text(r'<>',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
HtmlEditor(
controller: controller,
htmlEditorOptions: HtmlEditorOptions(
hint: 'Your text here...',
shouldEnsureVisible: true,
//initialText: "<p>text content initial, if any</p>",
),
htmlToolbarOptions: HtmlToolbarOptions(
toolbarPosition: ToolbarPosition.custom, //by default
// toolbarType: ToolbarType.nativeExpandable, //
onButtonPressed:
(ButtonType type, bool? status, Function? updateStatus) {
print(
"button '${describeEnum(type)}' pressed, the current selected status is $status");
return true;
},
onDropdownChanged: (DropdownType type, dynamic changed,
Function(dynamic)? updateSelectedItem) {
print(
"dropdown '${describeEnum(type)}' changed to $changed");
return true;
},
mediaLinkInsertInterceptor:
(String url, InsertFileType type) {
print(url);
return true;
},
mediaUploadInterceptor:
(PlatformFile file, InsertFileType type) async {
print(file.name); //filename
print(file.size); //size in bytes
print(file.extension); //file extension (eg jpeg or mp4)
return true;
},
),
otherOptions: OtherOptions(height: 700),
callbacks: Callbacks(onBeforeCommand: (String? currentHtml) {
print('html before change is $currentHtml');
}, onChangeContent: (String? changed) {
print('content changed to $changed');
}, onChangeCodeview: (String? changed) {
print('code changed to $changed');
}, onChangeSelection: (EditorSettings settings) {
print('parent element is ${settings.parentElement}');
print('font name is ${settings.fontName}');
}, onDialogShown: () {
print('dialog shown');
}, onEnter: () {
print('enter/return pressed');
}, onFocus: () {
print('editor focused');
}, onBlur: () {
print('editor unfocused');
}, onBlurCodeview: () {
print('codeview either focused or unfocused');
}, onInit: () {
print('init');
}, onImageUploadError:
(FileUpload? file, String? base64Str, UploadError error) {
print(describeEnum(error));
print(base64Str ?? '');
if (file != null) {
print(file.name);
print(file.size);
print(file.type);
}
}, onKeyDown: (int? keyCode) {
print('$keyCode key downed');
print(
'current character count: ${controller.characterCount}');
}, onKeyUp: (int? keyCode) {
print('$keyCode key released');
}, onMouseDown: () {
print('mouse downed');
}, onMouseUp: () {
print('mouse released');
}, onNavigationRequestMobile: (String url) {
print(url);
return NavigationActionPolicy.ALLOW;
}, onPaste: () {
print('pasted into editor');
}, onScroll: () {
print('editor scrolled');
}),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
width: 16,
),
TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.blueGrey),
onPressed: () {
controller.clear();
},
child: Text('清空', style: TextStyle(color: Colors.white)),
),
SizedBox(
width: 16,
),
TextButton(
style: TextButton.styleFrom(
backgroundColor:
Theme.of(context).colorScheme.secondary),
onPressed: () async {
var txt = await controller.getText();
if (txt.contains('src="data:')) {
txt =
'<text removed due to base-64 data, displaying the text could cause the app to crash>';
}
setState(() {
result = txt;
});
},
child: Text(
'提交',
style: TextStyle(color: Colors.white),
),
),
SizedBox(
width: 16,
),
TextButton(
style: TextButton.styleFrom(
backgroundColor:
Theme.of(context).colorScheme.secondary),
onPressed: () {
controller.insertText('Google');
},
child: Text('插入', style: TextStyle(color: Colors.white)),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
result,
style: TextStyle(color: Colors.white),
),
TextButton(
style: TextButton.styleFrom(
backgroundColor:
Theme.of(context).colorScheme.secondary),
onPressed: () {
controller.insertNetworkImage(
'https://luckly007.oss-cn-beijing.aliyuncs.com/macimages/image-20220713142248972.png',
filename: 'network image');
},
child: Text(
'插入图片',
style: TextStyle(color: Colors.white),
),
),
],
),
),
],
),
),
),
);
}
}
class descTitleWidget extends StatelessWidget {
const descTitleWidget({
Key? key,
required this.submit,
}) : super(key: key);

final String submit;

@override
Widget build(BuildContext context) {
return Container(
decoration: new BoxDecoration(
//背景
color: Color(0xFFF6F6F6),
//设置四周圆角 角度

borderRadius: BorderRadius.only(
topLeft: Radius.circular(24.w), topRight: Radius.circular(24.w)),
//设置四周边框
border: new Border.all(width: 1.w, color: Color(0x99CFD3E6)),
),
height: 96.w,
padding: EdgeInsets.only(
left: 28.w,
// top: 32.w,
right: 28.w),
width: MediaQuery.of(context).size.width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
submit,
style: currentTheme.ctd.subTitle * currentTheme.ctd.txtBlack,
),
Row(
children: [
SizedBox(
width: 124.w,
height: 52.w,
child: TextButton.icon(
onPressed: () async {
// var clipboardData = await Clipboard
// .getData(Clipboard
// .kTextPlain); //获取粘贴板中的文本
// if (clipboardData != null)
// _clipBoardData =
// clipboardData.text!;
// else
// _clipBoardData = "";
// int start = _quillController!
// .selection.start;
// _quillController!.document.insert(
// start, _clipBoardData);

// refreshUI();
},
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
primary: Colors.white,
backgroundColor: Colors.white,
textStyle: TextStyle(fontSize: 20.w),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(40.w))),
),
icon: Image.asset("images/circle-icon-paste.png"),
label: Text("粘贴",
style: TextStyle(
fontSize: 20.w,
color: Color_TitleBlack,
))),
),
SizedBox(width: 10.w),
SizedBox(
width: 124.w,
height: 52.w,
child: TextButton.icon(
onPressed: () {
// _picPicker();
},
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
primary: Colors.white,
backgroundColor: Colors.white,
textStyle: TextStyle(fontSize: 20.w),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(40.w))),
),
icon: Image.asset("images/circle-icon-album.png"),
label: Text("插图",
style: TextStyle(
fontSize: 20.w,
color: Color_TitleBlack,
))),
),
],
),
],
),
);
}
}

\

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  b1UHV4WKBb2S   2023年11月13日   25   0   0 flutterDart
w7nT9BWOuqag