Flutter富文本编辑器插件yogurt_editor的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter富文本编辑器插件yogurt_editor的使用

特性

自定义你的富文本编辑器。

开始使用

要开始使用该库,请在你的pubspec.yaml文件中添加以下依赖:

dependencies:
  yogurt_editor: any

使用示例

主程序

首先,我们需要创建一个主程序来运行我们的富文本编辑器。以下是完整的示例代码:

import 'dart:ui' as ui;

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

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: Example(),
      ),
    );
  }
}

class Example extends StatefulWidget {
  const Example({super.key});

  @override
  State<Example> createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  late final EditorController controller;

  static int _nextId = 0;

  static int _id() => _nextId++;

  @override
  void initState() {
    super.initState();
    controller = EditorController(
      root: CellState(
        id: _id(),
        model: CustomCellModel(
          builder: (context, state) {
            return const SizedBox();
          },
        ),
      ),
    );

    controller.create(CellState(
      id: _id(),
      model: const NodeModel(),
      all: const {
        Bounds: Bounds.fixed(
          left: 100,
          top: 100,
          width: 100,
          height: 100,
        ),
      },
    ));

    controller.create(CellState(
      id: _id(),
      model: const NodeModel(),
      all: const {
        Bounds: Bounds.fixed(
          left: 250,
          top: 150,
          width: 100,
          height: 100,
        ),
      },
    ));

    controller.create(
      CellState(
        id: _id(),
        model: const NodeModel(),
        all: const {
          String: 'inner text',
          Bounds: Bounds.intrinsic(
            top: 300,
            left: 300,
            delegate: IntrinsicBounds(),
          ),
        },
      ),
      extraPlugins: [
        const IntrinsicBoundsPlugin(
          delegate: IntrinsicBounds(),
        )
      ],
    );
  }

  @override
  void dispose() {
    controller.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return EditorView(
      controller: controller,
    );
  }
}

class NodeModel extends CellModelBase {
  const NodeModel();

  @override
  List<CellPluginBase> get plugins => const [
        BoundsPlugin(),
        DragPlugin(),
        DropPlugin(),
      ];

  @override
  Widget build(BuildContext context, CellState state) {
    return ColoredBox(
      color: Colors.blue,
      child: state.has<String>() ? Text(state()) : null,
    );
  }
}

class IntrinsicBounds extends IntrinsicBoundsDelegate {
  const IntrinsicBounds();

  @override
  Size computeDryLayout(CellController controller) {
    final builder = ui.ParagraphBuilder(ui.ParagraphStyle(
      fontSize: 14,
    ));

    builder.pushStyle(ui.TextStyle());
    builder.addText(controller.state<String>());

    final paragraph = builder.build();

    paragraph.layout(const ui.ParagraphConstraints(
      width: 120,
    ));

    return Size(paragraph.width, paragraph.height);
  }
}

代码解释

  • 导入必要的库

    import 'dart:ui' as ui;
    import 'package:flutter/material.dart';
    import 'package:yogurt_editor/yogurt_editor.dart';
    
  • 主程序入口

    void main() {
      runApp(const MainApp());
    }
    
  • 创建应用界面

    class MainApp extends StatelessWidget {
      const MainApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: Scaffold(
            body: Example(),
          ),
        );
      }
    }
    
  • 定义富文本编辑器状态管理

    class Example extends StatefulWidget {
      const Example({super.key});
    
      @override
      State<Example> createState() => _ExampleState();
    }
    
    class _ExampleState extends State<Example> {
      late final EditorController controller;
    
      static int _nextId = 0;
    
      static int _id() => _nextId++;
    
      @override
      void initState() {
        super.initState();
        controller = EditorController(
          root: CellState(
            id: _id(),
            model: CustomCellModel(
              builder: (context, state) {
                return const SizedBox();
              },
            ),
          ),
        );
    
        controller.create(CellState(
          id: _id(),
          model: const NodeModel(),
          all: const {
            Bounds: Bounds.fixed(
              left: 100,
              top: 100,
              width: 100,
              height: 100,
            ),
          },
        ));
    
        controller.create(CellState(
          id: _id(),
          model: const NodeModel(),
          all: const {
            Bounds: Bounds.fixed(
              left: 250,
              top: 150,
              width: 100,
              height: 100,
            ),
          },
        ));
    
        controller.create(
          CellState(
            id: _id(),
            model: const NodeModel(),
            all: const {
              String: 'inner text',
              Bounds: Bounds.intrinsic(
                top: 300,
                left: 300,
                delegate: IntrinsicBounds(),
              ),
            },
          ),
          extraPlugins: [
            const IntrinsicBoundsPlugin(
              delegate: IntrinsicBounds(),
            )
          ],
        );
      }
    
      @override
      void dispose() {
        controller.close();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return EditorView(
          controller: controller,
        );
      }
    }
    
  • 定义节点模型

    class NodeModel extends CellModelBase {
      const NodeModel();
    
      @override
      List<CellPluginBase> get plugins => const [
            BoundsPlugin(),
            DragPlugin(),
            DropPlugin(),
          ];
    
      @override
      Widget build(BuildContext context, CellState state) {
        return ColoredBox(
          color: Colors.blue,
          child: state.has<String>() ? Text(state()) : null,
        );
      }
    }
    
  • 定义内部边界委托

    class IntrinsicBounds extends IntrinsicBoundsDelegate {
      const IntrinsicBounds();
    
      @override
      Size computeDryLayout(CellController controller) {
        final builder = ui.ParagraphBuilder(ui.ParagraphStyle(
          fontSize: 14,
        ));
    
        builder.pushStyle(ui.TextStyle());
        builder.addText(controller.state<String>());
    
        final paragraph = builder.build();
    
        paragraph.layout(const ui.ParagraphConstraints(
          width: 120,
        ));
    
        return Size(paragraph.width, paragraph.height);
      }
    }
    

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

1 回复

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


当然,以下是一个关于如何在Flutter项目中使用yogurt_editor富文本编辑器插件的示例代码。这个示例将展示如何集成yogurt_editor、配置编辑器以及处理编辑器的内容。

首先,确保你已经在pubspec.yaml文件中添加了yogurt_editor依赖:

dependencies:
  flutter:
    sdk: flutter
  yogurt_editor: ^最新版本号  # 请替换为实际的最新版本号

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

接下来,在你的Flutter项目中创建一个使用yogurt_editor的页面。以下是一个完整的示例代码:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Yogurt Editor Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: YogurtEditorDemo(),
    );
  }
}

class YogurtEditorDemo extends StatefulWidget {
  @override
  _YogurtEditorDemoState createState() => _YogurtEditorDemoState();
}

class _YogurtEditorDemoState extends State<YogurtEditorDemo> {
  final YogurtController _controller = YogurtController();

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Yogurt Editor Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: YogurtEditor(
          controller: _controller,
          focusNode: FocusNode(),
          toolbarOptions: YogurtToolbarOptions(
            // 配置工具栏选项,这里使用默认配置
          ),
          initContent: 'Hello, Yogurt Editor!', // 初始化内容
          placeholder: 'Start typing...',
          maxLines: null, // 不限制行数
          expands: true, // 自动扩展高度
          readOnly: false, // 可编辑
          autoFocus: true, // 自动聚焦
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 获取编辑器内容
          final String content = _controller.text;
          // 打印内容到控制台(或进行其他处理)
          print('Editor Content: $content');
        },
        tooltip: 'Get Content',
        child: Icon(Icons.content_copy),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 引入依赖:在pubspec.yaml文件中添加了yogurt_editor依赖。
  2. 创建主应用:在MyApp类中定义了应用的主题和主页。
  3. 创建编辑器页面:在YogurtEditorDemo类中,使用YogurtEditor小部件创建了一个富文本编辑器。
  4. 控制器管理:使用YogurtController来管理编辑器的状态和内容。
  5. 工具栏配置:通过YogurtToolbarOptions配置工具栏选项(这里使用默认配置)。
  6. 获取内容:在浮动操作按钮(FAB)的点击事件中,通过_controller.text获取编辑器的内容并打印到控制台。

这个示例展示了如何在Flutter应用中使用yogurt_editor插件创建一个基本的富文本编辑器,并获取用户输入的内容。你可以根据需要进一步自定义和扩展这个示例。

回到顶部