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插件来创建和编辑富文本内容。你可以根据需要进一步自定义编辑器的功能和样式。
        
      
            
            
            
