Flutter Markdown解析与动态UI生成插件json_dynamic_widget_plugin_markdown的使用

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

Flutter Markdown解析与动态UI生成插件json_dynamic_widget_plugin_markdown的使用

目录


Live Example


简介

此插件为 JSON Dynamic Widget 提供了对 Markdown 的支持。


使用插件

import 'package:json_dynamic_widget/json_dynamic_widget.dart';
import 'package:json_dynamic_widget_plugin_markdown/json_dynamic_widget_plugin_markdown.dart';

void main() {
  // 确保 Flutter 的绑定已完成
  WidgetsFlutterBinding.ensureInitialized();

  // 获取注册表的实例
  var registry = JsonWidgetRegistry.instance;

  // 将插件绑定到注册表。这一步是必要的,以便注册表能够找到插件提供的小部件
  JsonMarkdownPluginRegistrar.registerDefaults(registry: registry);
}

示例代码

文件路径:example/lib/main.dart

import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:json_dynamic_widget/json_dynamic_widget.dart';
import 'package:json_dynamic_widget_plugin_markdown/json_dynamic_widget_plugin_markdown.dart';
import 'package:logging/logging.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  SchemaValidator.enabled = false;

  if (kDebugMode) {
    Logger.root.level = Level.FINE;
    Logger.root.onRecord.listen((record) {
      debugPrint(
        '[${record.loggerName}]: ${record.message}',
      );
      if (record.error != null) {
        debugPrint('${record.error}');
      }
      if (record.stackTrace != null) {
        debugPrint('${record.stackTrace}');
      }
    });
  } else {
    Logger.root.level = Level.INFO;
    Logger.root.onRecord.listen((record) {
      debugPrint(
        '[${record.loggerName}]: ${record.level.name}: ${record.time}: ${record.message}',
      );
      if (record.error != null) {
        debugPrint('${record.error}');
      }
      if (record.stackTrace != null) {
        debugPrint('${record.stackTrace}');
      }
    });
  }

  final navigatorKey = GlobalKey<NavigatorState>();

  final registry = JsonWidgetRegistry.instance;

  JsonMarkdownPluginRegistrar.registerDefaults(registry: registry);

  registry.navigatorKey = navigatorKey;

  final templates = {
    'json_dynamic_widget':
        'https://raw.githubusercontent.com/peiffer-innovations/json_dynamic_widget/main/README.md',
    'json_dynamic_widget_plugin_charts_flutter':
        'https://raw.githubusercontent.com/peiffer-innovations/json_dynamic_widget_plugin_charts_flutter/main/README.md',
    'json_dynamic_widget_plugin_expressions':
        'https://github.com/peiffer-innovations/json_dynamic_widget_plugin_expressions/raw/main/README.md',
    'json_dynamic_widget_plugin_font_awesome':
        'https://github.com/peiffer-innovations/json_dynamic_widget_plugin_font_awesome/raw/main/README.md',
    'json_dynamic_widget_plugin_ionicons':
        'https://github.com/peiffer-innovations/json_dynamic_widget_plugin_ionicons/raw/main/README.md',
    'json_dynamic_widget_plugin_lottie':
        'https://github.com/peiffer-innovations/json_dynamic_widget_plugin_lottie/raw/main/README.md',
    'json_dynamic_widget_plugin_markdown':
        'https://github.com/peiffer-innovations/json_dynamic_widget_plugin_markdown/raw/main/README.md',
    'json_dynamic_widget_plugin_material_icons':
        'https://github.com/peiffer-innovations/json_dynamic_widget_plugin_material_icons/raw/main/README.md',
    'json_dynamic_widget_plugin_rive':
        'https://github.com/peiffer-innovations/json_dynamic_widget_plugin_rive/raw/main/README.md',
    'json_dynamic_widget_plugin_svg':
        'https://github.com/peiffer-innovations/json_dynamic_widget_plugin_svg/raw/main/README.md',
  };

  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(
        templates: templates,
      ),
      theme: ThemeData.light(),
    ),
  );
}

class HomePage extends StatefulWidget {
  const HomePage({
    super.key,
    required this.templates,
  });

  final Map<String, String> templates;

  [@override](/user/override)
  HomePageState createState() => HomePageState();
}

class HomePageState extends State<HomePage> {
  late List<MapEntry<String, String>> _templates;
  int _loading = -1;

  [@override](/user/override)
  void initState() {
    super.initState();

    _templates = widget.templates.entries.toList();
  }

  Future<void> _navigate(int index, String title, String url) async {
    _loading = index;
    if (mounted) {
      setState(() {});
    }

    try {
      final response = await http.get(Uri.parse(url));
      final md = response.body;

      final registry = JsonWidgetRegistry.instance.copyWith();
      try {
        final data = JsonWidgetData.fromDynamic(
          json.decode(await rootBundle.loadString('assets/pages/markdown.json')),
          registry: registry,
        );
        registry.setValue('title', title);
        registry.setValue('data', md);

        if (mounted) {
          await Navigator.of(context).push(
            MaterialPageRoute(
              builder: (_) => JsonWidgetPage(data: data),
            ),
          );
        }
      } finally {
        registry.dispose();
      }
    } finally {
      _loading = -1;
      if (mounted) {
        setState(() {});
      }
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Markdown Widget'),
      ),
      body: ListView.builder(
        itemBuilder: (context, index) {
          final entry = _templates[index];
          return Stack(
            children: [
              ListTile(
                onTap: () => _loading == -1
                    ? _navigate(index, entry.key, entry.value)
                    : null,
                title: Text(entry.key),
              ),
              if (_loading == index)
                const Positioned(
                  bottom: 0.0,
                  left: 0.0,
                  right: 0.0,
                  child: LinearProgressIndicator(),
                )
            ],
          );
        },
        itemCount: _templates.length,
      ),
    );
  }
}

class JsonWidgetPage extends StatelessWidget {
  const JsonWidgetPage({
    super.key,
    required this.data,
  });

  final JsonWidgetData data;

  [@override](/user/override)
  Widget build(BuildContext context) => data.build(context: context);
}

更多关于Flutter Markdown解析与动态UI生成插件json_dynamic_widget_plugin_markdown的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Markdown解析与动态UI生成插件json_dynamic_widget_plugin_markdown的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter中使用 json_dynamic_widget_plugin_markdown 插件来解析 Markdown 并动态生成 UI 的代码示例。这个插件允许你使用 JSON 配置来动态生成 Flutter 组件,并且它还支持将 Markdown 文本解析为 Flutter 的 Widget。

首先,确保你的 Flutter 项目中已经添加了 json_dynamic_widgetjson_dynamic_widget_plugin_markdown 这两个依赖。你可以在你的 pubspec.yaml 文件中添加如下依赖:

dependencies:
  flutter:
    sdk: flutter
  json_dynamic_widget: ^x.y.z  # 替换为最新版本号
  json_dynamic_widget_plugin_markdown: ^x.y.z  # 替换为最新版本号

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

接下来,在你的 Flutter 项目的 Dart 文件中,你可以按照以下步骤使用 json_dynamic_widget_plugin_markdown 来解析 Markdown 并生成 UI。

import 'package:flutter/material.dart';
import 'package:json_dynamic_widget/json_dynamic_widget.dart';
import 'package:json_dynamic_widget_plugin_markdown/json_dynamic_widget_plugin_markdown.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Markdown 解析与动态 UI 生成'),
        ),
        body: DynamicWidgetBuilder.build({
          'type': 'Markdown',
          'data': '''
# 这是一个标题

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

- 项目一
- 项目二
- 项目三

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

// 注册 Markdown 插件
void registerPlugins(JsonDynamicWidgetPluginRegistry registry) {
  registry.registerPlugin<MarkdownBuilder>(
    'Markdown',
    () => MarkdownBuilder(),
  );
}

class MyAppWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return JsonDynamicWidgetBuilder(
      json: {
        'type': 'Column',
        'children': [
          {
            'type': 'Markdown',
            'data': '''
# 这是一个标题

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

- 项目一
- 项目二
- 项目三

[这是一个链接](https://flutter.dev)
            ''',
          },
        ],
      },
      plugins: [
        MarkdownBuilderPlugin(), // 注册 Markdown 插件
      ],
    );
  }
}

注意:

  1. 在上面的代码中,registerPlugins 函数用于注册 Markdown 插件。然而,这个例子中并未直接调用 registerPlugins,因为 json_dynamic_widget_plugin_markdown 插件通常在内部已经注册好了必要的插件。如果你需要手动注册插件,你可以使用类似 registerPlugins 的方法来注册。

  2. MyApp 类中,我们使用 DynamicWidgetBuilder.build 方法来直接解析 JSON 并生成 UI。在这个 JSON 中,我们指定了 typeMarkdown,并提供了 data 字段来包含 Markdown 文本。

  3. 你也可以定义一个自定义的 MyAppWidget 类,使用 JsonDynamicWidgetBuilder 组件,并传递包含 Markdown 的 JSON 数据。在这个例子中,我们没有使用 MyAppWidget,但你可以根据需求选择使用。

请确保你已经正确导入了所有必要的包,并且 JSON 数据格式正确。这样,你就可以在 Flutter 应用中解析 Markdown 并动态生成 UI 了。

回到顶部