Flutter富文本编辑器插件zero_story_editor的使用
Flutter富文本编辑器插件zero_story_editor的使用
本包是基于WhatsApp故事图像/视频编辑器风格创建的,您可以同时编辑图像和视频。您可以添加文字、贴纸、自由手绘、应用滤镜并撤销。编辑后的图像将以List of Files
的形式通过onSave
回调返回。然后您可以将它们上传到存储或保存到本地相册。
目前仅支持视频裁剪。未来会添加更多视频编辑功能。
功能
✅ 您可以同时编辑图像和视频。
✅ 可拖动的精美文字(自定义颜色、字体族和调整大小)。
✅ 可拖动的贴纸与表情符号。
✅ 对图像应用滤镜。
✅ 在图像上进行自由手绘。
✅ 裁剪视频帧。
未来功能
🚀 在视频帧上绘画(需要平台特定的工作)。
🚀 增加更多图像和视频编辑功能,如WhatsApp和Instagram故事。
🚀 当前UI类似于WhatsApp,但我们可以为Flutter设计一些独特的东西(您的贡献和想法非常有价值)。
🚀 改进和增强性能及现有功能。
包演示
安装
在pubspec.yaml
文件中添加flutter_story_editor: latest_version
,然后导入它。
import 'package:stories_editor/stories_editor.dart';
Android
在AndroidManifest.xml
文件中添加以下代码:
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
iOS
在info.plist
文件中添加以下代码:
<key>NSCameraUsageDescription</key>
<string>用于演示图像选择器插件</string>
<key>NSMicrophoneUsageDescription</key>
<string>用于捕获图像选择器插件的音频</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>用于演示图像选择器插件</string>
如何使用
// 在状态中初始化控制器
FlutterStoryEditorController controller = FlutterStoryEditorController();
final TextEditingController _captionController = TextEditingController();
// TODO: 创建一个方法来选择文件(视频和图像),要么单独选择,要么一起选择。
// 选择文件
selectMedia().then((value) {
if (_selectedMedia != null && _selectedMedia!.isNotEmpty) {
showModalBottomSheet(
isScrollControlled: true,
isDismissible: false,
enableDrag: false,
context: context,
builder: (context) {
return FlutterStoryEditor(
controller: controller,
captionController: _captionController,
selectedFiles: _selectedMedia,
onSaveClickListener: (files) {
// 这里你可以获取到你编辑过的文件。
}
);
},
);
}
},
);
}, icon: const Icon(Icons.upload, size: 50,)),
),
有关更多信息,请访问example/example.dart
中的示例项目。
截图
初始视图 & 多个图像选择
图像和视频一起 & 应用滤镜
裁剪、缩放和旋转 & 添加可拖动的贴纸
添加表情符号 & 添加可拖动的精美文字
在图像上自由手绘
必读
flutter_story_editor
的初始版本可能有一些小错误和问题。如果您发现了一些,并且愿意贡献,请随时创建问题并提交PR。请通过我的 LinkedIn 发送私信告知我您创建的问题,无论您是否愿意贡献。
随着时间的推移,此包将得到改进,您的贡献将非常宝贵。
创建 & 维护者
@MuhammadAdnan,LinkedIn : @MuhammadAdnan ,Instagram : @MuhammadAdnan。
YouTube : @eTechViral
示例代码
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_story_editor/flutter_story_editor.dart';
import 'package:flutter_story_editor/src/controller/controller.dart';
import 'package:path/path.dart' as path;
class FlutterStoryEditorExample extends StatefulWidget {
const FlutterStoryEditorExample({super.key});
[@override](/user/override)
State<FlutterStoryEditorExample> createState() => _FlutterStoryEditorExampleState();
}
class _FlutterStoryEditorExampleState extends State<FlutterStoryEditorExample> with SingleTickerProviderStateMixin {
FlutterStoryEditorController controller = FlutterStoryEditorController();
final TextEditingController _captionController = TextEditingController();
List<File>? _selectedMedia;
List<String>? _mediaTypes; // 存储每个选定文件的类型
Future<void> selectMedia() async {
setState(() {
_selectedMedia = null;
_mediaTypes = null;
});
try {
final result = await FilePicker.platform.pickFiles(
type: FileType.media,
allowMultiple: true,
);
if (result != null) {
_selectedMedia = result.files.map((file) => File(file.path!)).toList();
// 初始化媒体类型列表
_mediaTypes = List<String>.filled(_selectedMedia!.length, '');
// 确定每个选定文件的类型
for (int i = 0; i < _selectedMedia!.length; i++) {
String extension = path.extension(_selectedMedia![i].path).toLowerCase();
if (extension == '.jpg' || extension == '.jpeg' || extension == '.png') {
_mediaTypes![i] = 'image';
} else if (extension == '.mp4' || extension == '.mov' || extension == '.avi') {
_mediaTypes![i] = 'video';
}
}
setState(() {});
} else {
// 用户取消了文件选择
}
} catch (e) {
throw Exception("无法选择文件,请重试");
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: IconButton(
onPressed: () {
selectMedia().then(
(value) {
if (_selectedMedia != null && _selectedMedia!.isNotEmpty) {
showModalBottomSheet(
isScrollControlled: true,
isDismissible: false,
enableDrag: false,
context: context,
builder: (context) {
return FlutterStoryEditor(
controller: controller,
captionController: _captionController,
selectedFiles: _selectedMedia,
onSaveClickListener: (files) {
// 这里你可以获取到你编辑过的文件。
}
);
},
);
}
},
);
},
icon: const Icon(Icons.upload, size: 50,),
),
),
const SizedBox(height: 10),
const Text("选择文件并玩转它们")
],
),
);
}
}
更多关于Flutter富文本编辑器插件zero_story_editor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter富文本编辑器插件zero_story_editor的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用zero_story_editor
富文本编辑器插件的示例代码。这个插件允许你创建和编辑富文本内容。为了使用它,你需要先确保在pubspec.yaml
文件中添加了依赖项。
1. 添加依赖项
在你的pubspec.yaml
文件中,添加以下依赖项:
dependencies:
flutter:
sdk: flutter
zero_story_editor: ^最新版本号 # 请替换为实际发布的最新版本号
然后运行flutter pub get
来获取依赖项。
2. 导入包
在你的Dart文件中导入zero_story_editor
包:
import 'package:zero_story_editor/zero_story_editor.dart';
3. 使用ZeroStoryEditor
以下是一个完整的示例,展示如何在Flutter应用中使用ZeroStoryEditor
:
import 'package:flutter/material.dart';
import 'package:zero_story_editor/zero_story_editor.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final ZeroStoryController _controller = ZeroStoryController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Zero Story Editor Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: ZeroStoryEditor(
controller: _controller,
placeholder: 'Start writing...',
toolbarOptions: [
ToolbarOptions.bold,
ToolbarOptions.italic,
ToolbarOptions.underline,
ToolbarOptions.heading1,
ToolbarOptions.heading2,
ToolbarOptions.paragraph,
ToolbarOptions.quote,
ToolbarOptions.link,
ToolbarOptions.image,
],
),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
// 获取富文本内容
_controller.getText().then((text) {
print('Editor Content: $text');
});
},
child: Text('Get Editor Content'),
),
],
),
),
);
}
@override
void dispose() {
// 释放控制器资源
_controller.dispose();
super.dispose();
}
}
解释
- 依赖项:在
pubspec.yaml
中添加zero_story_editor
依赖项。 - 导入包:在Dart文件中导入
zero_story_editor
包。 - 创建控制器:创建一个
ZeroStoryController
实例,用于管理编辑器的状态。 - 构建UI:使用
ZeroStoryEditor
小部件来创建富文本编辑器,并配置工具栏选项。 - 获取内容:通过
_controller.getText()
方法获取编辑器中的内容,并在控制台中打印出来。 - 释放资源:在
dispose
方法中释放控制器资源,以避免内存泄漏。
这个示例展示了如何在Flutter应用中使用zero_story_editor
插件来创建和编辑富文本内容。你可以根据需要进一步自定义编辑器的功能和样式。