Flutter Markdown渲染插件flame_markdown的使用

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

Flutter Markdown渲染插件 flame_markdown 的使用

flame_markdown 是一个用于在 Flame 游戏引擎中解析和渲染 Markdown 文本的插件。它通过将 Markdown 字符串转换为抽象语法树(AST),然后利用这个 AST 创建 Flame 的文本节点层次结构,从而简化了游戏中的文本格式化工作。

功能概述

  • 支持简单的内联格式:如加粗、斜体等。
  • 复杂文档创建:可以创建带有标题和段落的复杂文本文档,并由 Flame 的文本布局系统进行格式化。
  • 无需手动构建 TextNode 树结构:自动根据 Markdown 内容生成相应的文本节点层次。

添加依赖

首先,在你的 pubspec.yaml 文件中添加 flame_markdown 作为依赖项:

dependencies:
  flame: ^1.0.0 # 确保使用兼容版本
  flame_markdown: ^1.0.0
  markdown: ^5.0.0 # 依赖于markdown包

之后运行 flutter pub get 来安装这些依赖。

示例 Demo

下面是一个完整的示例代码,展示了如何在一个 Flame 游戏中使用 flame_markdown 插件来渲染富文本组件。

完整示例代码

import 'dart:async';
import 'package:flame/components.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame/text.dart';
import 'package:flame_markdown/flame_markdown.dart';
import 'package:flutter/widgets.dart' hide Animation;
import 'package:markdown/markdown.dart';

void main() {
  runApp(GameWidget(game: MarkdownGame()));
}

/// 这个例子展示了如何使用 FlameMarkdown 包
/// 通过简单的 Markdown 语法来渲染富文本组件。
class MarkdownGame extends FlameGame {
  [@override](/user/override)
  Future<void> onLoad() async {
    // 加载包含 Markdown 内容的文件
    final markdown = await Flame.assets.readFile('fire_and_ice.md');
    
    // 将 Markdown 转换为 Flame 文档对象
    final document = FlameMarkdown.toDocument(
      markdown,
      document: Document(
        encodeHtml: false,
        inlineSyntaxes: [
          StrikethroughSyntax(), // 支持删除线
        ],
      ),
    );

    // 创建并添加 TextElementComponent 到游戏中
    await add(
      TextElementComponent.fromDocument(
        document: document,
        style: DocumentStyle(
          padding: const EdgeInsets.all(16),
        ),
        size: size, // 设置组件大小
      ),
    );
    
    await super.onLoad();
  }
}

更多关于Flutter Markdown渲染插件flame_markdown的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Markdown渲染插件flame_markdown的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用flame_markdown插件来渲染Markdown内容的示例代码。flame_markdown是一个用于Flutter的Markdown渲染库,虽然它通常与Flame游戏引擎一起使用,但你也可以单独使用它来渲染Markdown文本。

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

dependencies:
  flutter:
    sdk: flutter
  flame: ^1.0.0  # 确保你添加了Flame的依赖,尽管不是严格必需,但通常一起使用
  flame_markdown: ^x.y.z  # 替换为最新版本号

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

接下来,在你的Flutter项目中创建一个新的Dart文件(例如markdown_page.dart),并编写以下代码:

import 'package:flutter/material.dart';
import 'package:flame/flame.dart';
import 'package:flame_markdown/flame_markdown.dart';

class MarkdownPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Markdown内容示例
    final String markdownContent = """
    # 这是一个标题

    这是一个段落,**加粗** 和 *斜体* 文本。

    - 项目1
    - 项目2
    - 项目3

    ```dart
    void main() {
      print("Hello, World!");
    }
    ```

    [这是一个链接](https://flutter.dev)
    """;

    // 使用FlameMarkdown组件渲染Markdown内容
    return Scaffold(
      appBar: AppBar(
        title: Text('Markdown 渲染示例'),
      ),
      body: FlameWidget(
        game: MarkdownGame(markdown: markdownContent),
      ),
    );
  }
}

// 自定义Game类,用于渲染Markdown
class MarkdownGame extends Game {
  final String markdown;

  MarkdownGame({required this.markdown});

  @override
  void render(Canvas canvas) {
    // 这里不直接使用Canvas渲染,而是利用FlameMarkdown组件
    // 因为FlameMarkdown不是直接继承自CanvasRenderable,所以我们需要一些变通方法
    // 在这个例子中,我们使用Overlay来展示Markdown内容
    final size = Flame.util.screenSize;
    final batch = Batch();

    // 创建一个组件来渲染Markdown内容
    final markdownWidget = MarkdownWidget(data: markdown);

    // 使用一个全局键来获取MarkdownWidget的RenderBox
    final GlobalKey markdownKey = GlobalKey();
    final Widget markdownContainer = Container(
      key: markdownKey,
      child: markdownWidget,
    );

    // 这里我们不实际将markdownContainer添加到Flutter的Widget树中
    // 而是利用LayoutBuilder来测量其大小并获取RenderBox
    LayoutBuilder({ required BoxConstraints constraints }) {
      final renderBox = markdownKey.currentContext?.findRenderObject() as RenderBox?;
      if (renderBox != null) {
        // 获取MarkdownWidget在屏幕上的位置和大小
        final position = renderBox.localToGlobal(Offset.zero);
        final size = renderBox.size;

        // 这里我们本应该使用canvas来绘制,但由于Flutter的RenderBox不能直接绘制到Canvas上
        // 我们需要另一种方法来显示它。在实际应用中,你可能需要将其绘制到Image或其他可绘制对象上,
        // 或者直接将其添加到Flutter的Widget树中(不是在这个Game的render方法中)。
        // 为简单起见,这里我们省略了实际的绘制步骤,并假设你已经知道如何在Flutter中显示这个Widget。

        // 注意:下面的代码仅用于说明如何获取RenderBox,并不实际绘制到Canvas上。
        print('Markdown Widget Position: $position, Size: $size');
      }
      return Container(); // 返回一个空容器,因为我们不在这里实际渲染
    }(constraints: BoxConstraints.tightFor(width: size.width, height: size.height));

    // 注意:上面的代码片段是为了说明如何获取RenderBox,但在Flame中直接这样使用并不合适。
    // 更好的做法是在Flutter的Widget树中直接使用MarkdownWidget,而不是在Game的render方法中。
    // 因此,下面的代码才是更实际的使用方法:

    // 直接在Flutter的Widget树中使用MarkdownWidget(推荐方法)
    // 注意:这里我们不会真的在Game的render方法里做这件事,而是应该在Flutter的Widget层处理。
    // 但为了完整性,这里展示如何在Flutter的Widget中使用MarkdownWidget。
    // return MaterialApp(
    //   home: Scaffold(
    //     appBar: AppBar(title: Text('Markdown 渲染')),
    //     body: Center(child: markdownWidget),
    //   ),
    // );

    // 由于我们是在Game的render方法中,实际上我们不会返回任何Widget。
    // 这里的代码只是为了展示如何在Flutter中集成MarkdownWidget。
    // 在实际的Flame+Flutter项目中,你可能需要设计一种机制来在Game和Flutter的Widget之间通信。
  }

  @override
  void update(double delta) {}

  @override
  void resize(Vector2 size) {}

  @override
  void shutdown() {}
}

// 注意:上面的MarkdownGame类的render方法中的代码主要是为了说明目的,
// 在实际项目中,你应该避免在Game的render方法中直接操作Flutter的Widget。
// 更好的做法是在Flutter的Widget层直接使用MarkdownWidget,如上面的注释所示。

// 在你的主应用中引入MarkdownPage
void main() {
  runApp(MaterialApp(
    home: MarkdownPage(),
  ));
}

重要说明

  1. 上面的MarkdownGame类中的render方法包含了一些不实际用于生产的代码,主要是为了说明如何获取RenderBox。在实际应用中,你应该避免在Game的render方法中直接操作Flutter的Widget。

  2. 更推荐的做法是在Flutter的Widget层直接使用MarkdownWidget,而不是在Game的render方法中。例如,你可以直接在MarkdownPagebuild方法中使用MarkdownWidget,而不是通过FlameWidgetGame

  3. 由于flame_markdown通常与Flame游戏引擎一起使用,你可能需要根据你的项目需求调整集成方式。如果你的项目不是游戏,那么直接使用Flutter的Markdown库(如flutter_markdown)可能更加简单和直接。

  4. 上面的代码示例可能需要根据flame_markdown和Flutter的最新API进行调整。确保查阅最新的文档和示例代码。

希望这个示例能帮助你在Flutter项目中使用flame_markdown来渲染Markdown内容!

回到顶部