Flutter文档增强插件admonitions的使用

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

Flutter文档增强插件admonitions的使用

admonitions 是一个用于在Flutter应用中显示消息、警告、信息等的漂亮横幅式小部件。它受到了Docusaurus的admonitions功能的启发。

特性

该插件提供了三种可用样式:

  • Solid
  • Pastel
  • Classic

示例

下面是一个完整的示例,展示了如何在Flutter应用中使用 admonitions 插件。你可以直接运行这个示例代码来查看效果。

完整示例代码

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

void main() => runApp(const MyApp());

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

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  ThemeMode _theme = ThemeMode.system;

  // 切换主题
  void _toggleTheme() {
    setState(() {
      switch (_theme) {
        case ThemeMode.light:
          _theme = ThemeMode.dark;
          break;
        case ThemeMode.dark:
          _theme = ThemeMode.system;
          break;
        case ThemeMode.system:
          _theme = ThemeMode.light;
          break;
      }
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Admonition Demo',
      theme: ThemeData.light(useMaterial3: true),
      darkTheme: ThemeData.dark(useMaterial3: true),
      themeMode: _theme,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Admonition Demo'),
          actions: [
            IconButton(
              tooltip: "Toggle light/dark/system theme",
              onPressed: _toggleTheme,
              icon: Icon(
                switch (_theme) {
                  ThemeMode.light => Icons.light_mode_rounded,
                  ThemeMode.dark => Icons.dark_mode_rounded,
                  ThemeMode.system => Icons.brightness_auto_rounded,
                },
              ),
            )
          ],
        ),
        body: const MyHomePage(),
      ),
    );
  }
}

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              'Solid Admonition',
              style: Theme.of(context).textTheme.headlineSmall,
            ),
            const SolidAdmonition.note(
              text: '(Note) You might read this, you might not.',
            ),
            const SolidAdmonition.tip(
              text: '(Tip) You want to read this.',
            ),
            const SolidAdmonition.info(
              text: '(Info/Important) You should read this.',
            ),
            const SolidAdmonition.caution(
              text: '(Caution) I hope you read this.',
            ),
            const SolidAdmonition.danger(
              text: '(Danger) You need to read this.',
            ),
            const SolidAdmonition(
              text: '(Raw) Background colour is defaulted to your app primary colour.',
            ),
            const Divider(),
            Text(
              'Pastel Admonition',
              style: Theme.of(context).textTheme.headlineSmall,
            ),
            const PastelAdmonition.note(
              text: '(Note) You might read this, you might not.',
            ),
            const PastelAdmonition.tip(
              text: '(Tip) You want to read this.',
            ),
            const PastelAdmonition.info(
              text: '(Info/Important) You should read this.',
            ),
            const PastelAdmonition.caution(
              text: '(Caution) I hope you read this.',
            ),
            const PastelAdmonition.danger(
              text: '(Danger) You need to read this.',
            ),
            const PastelAdmonition(
              text: '(Raw) Background colour is defaulted to your app primary colour.',
            ),
            const Divider(),
            Text(
              '...with actions',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            PastelAdmonition.caution(
              text: '(Caution) I hope you read this. With action button below.',
              actions: [
                TextButton(
                    style: TextButton.styleFrom(
                      foregroundColor: Theme.of(context).textTheme.bodyLarge!.color,
                      tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                      textStyle: const TextStyle(fontWeight: FontWeight.w600),
                    ),
                    onPressed: () {
                      ScaffoldMessenger.of(context).removeCurrentSnackBar();
                      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                        content: Text('Button 1 pressed'),
                        behavior: SnackBarBehavior.floating,
                      ));
                    },
                    child: const Text('Action 1')),
                TextButton(
                    style: TextButton.styleFrom(
                      foregroundColor: Theme.of(context).textTheme.bodyLarge!.color,
                      tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                      textStyle: const TextStyle(fontWeight: FontWeight.w600),
                    ),
                    onPressed: () {
                      ScaffoldMessenger.of(context).removeCurrentSnackBar();
                      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                        content: Text('Button 2 pressed'),
                        behavior: SnackBarBehavior.floating,
                      ));
                    },
                    child: const Text('Action 2'))
              ],
            ),
            SolidAdmonition.info(
              text: '(Info/Important) You should read this. With action button below.',
              actions: [
                TextButton(
                    style: TextButton.styleFrom(
                      foregroundColor: Theme.of(context).textTheme.bodyLarge!.color,
                      tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                      textStyle: const TextStyle(fontWeight: FontWeight.w600),
                    ),
                    onPressed: () {
                      ScaffoldMessenger.of(context).removeCurrentSnackBar();
                      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                        content: Text('Button 1 pressed'),
                        behavior: SnackBarBehavior.floating,
                      ));
                    },
                    child: const Text('Action 1')),
                TextButton(
                    style: TextButton.styleFrom(
                      foregroundColor: Theme.of(context).textTheme.bodyLarge!.color,
                      tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                      textStyle: const TextStyle(fontWeight: FontWeight.w600),
                    ),
                    onPressed: () {
                      ScaffoldMessenger.of(context).removeCurrentSnackBar();
                      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                        content: Text('Button 2 pressed'),
                        behavior: SnackBarBehavior.floating,
                      ));
                    },
                    child: const Text('Action 2'))
              ],
            ),
            const Divider(),
            Text(
              'Classic Admonitions',
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const ClassicAdmonition.note(
              text: '(Note) You might read this, you might not.',
            ),
            const ClassicAdmonition.tip(
              text: '(Tip) You want to read this.',
            ),
            const ClassicAdmonition.info(
              text: '(Info/Important) You should read this.',
            ),
            const ClassicAdmonition.caution(
              text: '(Caution) I hope you read this.',
            ),
            const ClassicAdmonition.danger(
              text: '(Danger) You need to read this.',
            ),
            const ClassicAdmonition(
              text: '(Raw) Background colour is defaulted to your app primary colour.',
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter文档增强插件admonitions的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文档增强插件admonitions的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,文档增强插件admonitions通常用于在Markdown文档中插入不同类型的提示或警告框,以提升文档的可读性和信息的突出显示。这在创建开发者文档、教程或任何需要强调特定信息的场景中非常有用。以下是如何在Flutter项目中使用flutter_markdown包结合自定义的admonition样式来实现这一功能的示例代码。

首先,确保你的pubspec.yaml文件中包含flutter_markdown依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_markdown: ^0.x.x  # 请替换为最新版本号

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

接下来,我们需要自定义Markdown的渲染逻辑以支持admonitions。Flutter的flutter_markdown包本身不直接支持admonitions,但我们可以通过扩展MarkdownBody和自定义样式来实现这一功能。

以下是一个简单的示例,展示如何创建和使用自定义admonitions:

  1. 创建一个自定义Admonition类
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';

class Admonition extends StatelessWidget {
  final String title;
  final String content;
  final Color color;

  Admonition({required this.title, required this.content, required this.color});

  @override
  Widget build(BuildContext context) {
    return Card(
      color: color,
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(
              title,
              style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
            ),
            const SizedBox(height: 8.0),
            MarkdownBody(
              data: content,
              styleSheet: MarkdownStyleSheet.fromTheme(Theme.of(context)).copyWith(
                bodyText: TextStyle(color: Colors.white),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
  1. 创建一个自定义Markdown渲染器
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'admonition.dart';  // 假设Admonition类定义在这个文件中

class CustomMarkdownRenderer extends MarkdownBodyBuilderDelegate {
  @override
  void visitElementAfter(MarkdownElement element) {
    if (element is MarkdownBlockElement && element.asPlainText.startsWith('!!! ')) {
      final titleEnd = element.asPlainText.indexOf('\n');
      final title = element.asPlainText.substring(4, titleEnd).trim();
      final content = element.asPlainText.substring(titleEnd + 1).trim();
      final admonitionType = title.toLowerCase(); // 简单的类型判断,可以根据需要扩展
      Color color;

      switch (admonitionType) {
        case 'note':
          color = Colors.blue;
          break;
        case 'warning':
          color = Colors.amber;
          break;
        case 'danger':
          color = Colors.red;
          break;
        default:
          color = Colors.grey;
      }

      final admonitionWidget = Admonition(title: title, content: content, color: color);
      children.add(admonitionWidget);
    } else {
      super.visitElementAfter(element);
    }
  }
}
  1. 使用自定义渲染器渲染Markdown
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'custom_markdown_renderer.dart';  // 假设自定义渲染器定义在这个文件中

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Admonition Example')),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Markdown(
            data: '''
# Example of Admonitions

!!! note
    This is a note admonition.
    - It contains a bullet point.

!!! warning
    This is a warning admonition.
    - Be careful!

!!! danger
    This is a danger admonition.
    - Do not proceed!
            ''',
            builderDelegate: CustomMarkdownRenderer(),
          ),
        ),
      ),
    );
  }
}

在这个示例中,我们定义了一个Admonition小部件来表示admonition块,并根据admonition的类型(如note, warning, danger)应用不同的颜色。然后,我们创建了一个自定义的MarkdownBodyBuilderDelegate,它在遇到以!!!开头的Markdown块时,解析标题和内容,并创建一个相应的Admonition小部件。最后,我们在Markdown小部件中使用这个自定义渲染器来渲染Markdown文本。

这种方法允许你在Flutter应用中灵活地展示admonitions,并根据需要轻松扩展和自定义它们的样式和行为。

回到顶部