Flutter富文本编辑插件editor_widgets的使用

Flutter富文本编辑插件editor_widgets的使用

特性

  • DockLayout 小部件用于实现类似停靠体验。
  • TabbedLayout 小部件。

开始使用

要开始使用 editor_widgets 插件,请先将其添加到你的 pubspec.yaml 文件中:

dependencies:
  editor_widgets: ^x.y.z

然后运行 flutter pub get 来获取依赖项。

接下来,我们将通过一个完整的示例来展示如何使用这些小部件。

示例代码

主文件

import 'package:editor_widgets/tabbed_document.dart';
import 'package:flutter/material.dart';
import 'package:editor_widgets/dock_element.dart';
import 'package:editor_widgets/dock_layout.dart';
import 'package:editor_widgets/dock_side.dart';
import 'package:editor_widgets/dock_toolbar.dart';
import 'package:editor_widgets/tabbed_layout.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // 这个小部件是你的应用的根。
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late DockLayout _dock;
  final GlobalKey<TabbedLayoutState> _tabbedLayoutKey = GlobalKey();

  @override
  void initState() {
    super.initState();

    _dock = DockLayout(
      topPane: false,
      leftPaneToolbar: const DockToolbar(
          part1: [DockSide.topLeft, DockSide.leftTop],
          part2: [DockSide.leftBottom, DockSide.bottomLeft]),
      rightPaneToolbar: const DockToolbar(
          part1: [DockSide.topRight, DockSide.rightTop],
          part2: [DockSide.rightBottom, DockSide.bottomRight]),
      elements: const [
        DockElement(
          id: 'Explorer',
          name: 'Explorer',
          widget: Center(
            child: Text('Explorer'),
          ),
          icon: Icon(
            Icons.folder_outlined,
            color: Colors.grey,
          ),
          preferredDockSide: DockSide.leftTop,
          visible: true),
        DockElement(
          id: 'Messages',
          name: 'Messages',
          widget: Center(
            child: Text('Messages'),
          ),
          preferredDockSide: DockSide.rightTop,
          visible: true),
        DockElement(
          id: 'Info',
          name: 'Info',
          widget: Center(
            child: Text('Info'),
          ),
          preferredDockSide: DockSide.bottomLeft,
          visible: true),
      ],
      child: TabbedLayout(
        key: _tabbedLayoutKey,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          // 工具栏模拟
          Container(
            height: 50,
            decoration: BoxDecoration(
                border:
                    Border(bottom: BorderSide(color: Colors.grey.shade300))),
            child: Padding(
              padding: const EdgeInsets.only(left: 16.0),
              child: Row(
                children: [
                  InkWell(
                    onTap: () {
                      if (_tabbedLayoutKey.currentState != null) {
                        _tabbedLayoutKey.currentState!.container
                            .addDocument(TabbedDocument(
                          name: 'name',
                          icon: const Icon(Icons.file_copy),
                          widgetBuilder: (context) {
                            return TextFormField(
                              expands: true,
                              maxLines: null,
                              minLines: null,
                            );
                          },
                        ));
                        // print(_tabbedLayoutKey.currentState!.container.documents.length);
                        setState(() {});
                      }
                    },
                    child: const Padding(
                      padding: EdgeInsets.all(8.0),
                      child: Text('添加空白文档'),
                    ),
                  )
                ],
              ),
            ),
          ),
          Expanded(child: _dock),
          // 状态栏模拟
          Container(
            width: double.infinity,
            decoration: BoxDecoration(
                color: Colors.grey.shade100,
                border: Border(
                    top: BorderSide(color: Colors.grey.shade300, width: 1))),
            child: const Padding(
              padding: EdgeInsets.only(left: 12.0),
              child: Text('状态栏...'),
            ),
          )
        ],
      ),
    );
  }
}

说明

  1. 导入必要的包

    import 'package:editor_widgets/tabbed_document.dart';
    import 'package:flutter/material.dart';
    import 'package:editor_widgets/dock_element.dart';
    import 'package:editor_widgets/dock_layout.dart';
    import 'package:editor_widgets/dock_side.dart';
    import 'package:editor_widgets/dock_toolbar.dart';
    import 'package:editor_widgets/tabbed_layout.dart';
    
  2. 定义主应用类 MyApp

    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
            useMaterial3: true,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
  3. 定义主页状态类 _MyHomePageState

    class _MyHomePageState extends State<MyHomePage> {
      late DockLayout _dock;
      final GlobalKey<TabbedLayoutState> _tabbedLayoutKey = GlobalKey();
    
      @override
      void initState() {
        super.initState();
    
        _dock = DockLayout(
          topPane: false,
          leftPaneToolbar: const DockToolbar(
              part1: [DockSide.topLeft, DockSide.leftTop],
              part2: [DockSide.leftBottom, DockSide.bottomLeft]),
          rightPaneToolbar: const DockToolbar(
              part1: [DockSide.topRight, DockSide.rightTop],
              part2: [DockSide.rightBottom, DockSide.bottomRight]),
          elements: const [
            DockElement(
              id: 'Explorer',
              name: 'Explorer',
              widget: Center(
                child: Text('Explorer'),
              ),
              icon: Icon(
                Icons.folder_outlined,
                color: Colors.grey,
              ),
              preferredDockSide: DockSide.leftTop,
              visible: true),
            DockElement(
              id: 'Messages',
              name: 'Messages',
              widget: Center(
                child: Text('Messages'),
              ),
              preferredDockSide: DockSide.rightTop,
              visible: true),
            DockElement(
              id: 'Info',
              name: 'Info',
              widget: Center(
                child: Text('Info'),
              ),
              preferredDockSide: DockSide.bottomLeft,
              visible: true),
          ],
          child: TabbedLayout(
            key: _tabbedLayoutKey,
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: [
              // 工具栏模拟
              Container(
                height: 50,
                decoration: BoxDecoration(
                    border:
                        Border(bottom: BorderSide(color: Colors.grey.shade300))),
                child: Padding(
                  padding: const EdgeInsets.only(left: 16.0),
                  child: Row(
                    children: [
                      InkWell(
                        onTap: () {
                          if (_tabbedLayoutKey.currentState != null) {
                            _tabbedLayoutKey.currentState!.container
                                .addDocument(TabbedDocument(
                              name: 'name',
                              icon: const Icon(Icons.file_copy),
                              widgetBuilder: (context) {
                                return TextFormField(
                                  expands: true,
                                  maxLines: null,
                                  minLines: null,
                                );
                              },
                            ));
                            setState(() {});
                          }
                        },
                        child: const Padding(
                          padding: EdgeInsets.all(8.0),
                          child: Text('添加空白文档'),
                        ),
                      )
                    ],
                  ),
                ),
              ),
              Expanded(child: _dock),
              // 状态栏模拟
              Container(
                width: double.infinity,
                decoration: BoxDecoration(
                    color: Colors.grey.shade100,
                    border: Border(
                        top: BorderSide(color: Colors.grey.shade300, width: 1))),
                child: const Padding(
                  padding: EdgeInsets.only(left: 12.0),
                  child: Text('状态栏...'),
                ),
              )
            ],
          ),
        );
      }
    }
    

更多关于Flutter富文本编辑插件editor_widgets的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter富文本编辑插件editor_widgets的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


editor_widgets 是一个用于 Flutter 的富文本编辑插件,它允许你在应用中嵌入一个功能丰富的文本编辑器。以下是如何使用 editor_widgets 插件的基本步骤。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 editor_widgets 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  editor_widgets: ^0.0.1  # 请确保使用最新版本

然后运行 flutter pub get 来安装依赖。

2. 导入包

在你的 Dart 文件中导入 editor_widgets 包:

import 'package:editor_widgets/editor_widgets.dart';

3. 使用 EditorWidget

EditorWidgeteditor_widgets 中用于富文本编辑的主要组件。你可以像使用其他 Flutter 组件一样使用它。

class MyEditorPage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('富文本编辑器'),
      ),
      body: EditorWidget(
        onChanged: (String value) {
          print('当前内容: $value');
        },
        initialContent: '<p>初始内容</p>',
      ),
    );
  }
}

4. 处理富文本内容

EditorWidget 提供了 onChanged 回调,当用户编辑文本时,这个回调会被触发,并且会返回当前的 HTML 内容。

你可以通过 initialContent 属性来设置编辑器的初始内容。内容可以是 HTML 格式的字符串。

5. 获取编辑器内容

如果你需要在某个时刻获取编辑器的内容,可以使用 EditorController

class MyEditorPage extends StatefulWidget {
  [@override](/user/override)
  _MyEditorPageState createState() => _MyEditorPageState();
}

class _MyEditorPageState extends State<MyEditorPage> {
  final EditorController _controller = EditorController();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('富文本编辑器'),
      ),
      body: Column(
        children: [
          EditorWidget(
            controller: _controller,
            initialContent: '<p>初始内容</p>',
          ),
          ElevatedButton(
            onPressed: () {
              String content = _controller.getContent();
              print('编辑器内容: $content');
            },
            child: Text('获取内容'),
          ),
        ],
      ),
    );
  }
}

6. 自定义编辑器

EditorWidget 提供了多种自定义选项,例如工具栏的配置、编辑器的样式等。你可以根据需要进行定制。

EditorWidget(
  toolbarOptions: ToolbarOptions(
    bold: true,
    italic: true,
    underline: true,
    // 其他工具栏选项
  ),
  editorStyle: EditorStyle(
    backgroundColor: Colors.white,
    padding: EdgeInsets.all(10),
    // 其他样式选项
  ),
);

7. 其他功能

editor_widgets 还支持插入图片、链接、表格等高级功能。你可以查看插件的文档以获取更多详细信息。

8. 注意事项

  • editor_widgets 依赖于 WebView,因此在使用时可能需要处理 WebView 的相关配置和权限。
  • 由于 WebView 的性能和兼容性问题,editor_widgets 在某些设备上可能会有性能问题。

9. 示例代码

以下是一个完整的示例代码:

import 'package:flutter/material.dart';
import 'package:editor_widgets/editor_widgets.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter 富文本编辑器',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyEditorPage(),
    );
  }
}

class MyEditorPage extends StatefulWidget {
  [@override](/user/override)
  _MyEditorPageState createState() => _MyEditorPageState();
}

class _MyEditorPageState extends State<MyEditorPage> {
  final EditorController _controller = EditorController();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('富文本编辑器'),
      ),
      body: Column(
        children: [
          EditorWidget(
            controller: _controller,
            initialContent: '<p>初始内容</p>',
            toolbarOptions: ToolbarOptions(
              bold: true,
              italic: true,
              underline: true,
            ),
            editorStyle: EditorStyle(
              backgroundColor: Colors.white,
              padding: EdgeInsets.all(10),
            ),
          ),
          ElevatedButton(
            onPressed: () {
              String content = _controller.getContent();
              print('编辑器内容: $content');
            },
            child: Text('获取内容'),
          ),
        ],
      ),
    );
  }
}
回到顶部