FlutterでMarkdownを簡単に表示できるflutter_markdown_plus

Flutterアプリで、サーバーから取得した文章やユーザーが入力したコンテンツを表示する場合、単純なプレーンテキストではなく、

  • 見出し
  • 太字
  • 斜体
  • リスト
  • リンク
  • テーブル
  • コードブロック
  • 画像

などを含むリッチなコンテンツとして表示したいケースがあります。

特に、ブログやドキュメント、AIチャット、ヘルプページなどではMarkdown形式のデータを扱うことが多くなっています。

そんなときに便利なのが flutter_markdown_plus パッケージです。

flutter_markdown_plus は、Googleが開発・メンテナンスしていた flutter_markdown の後継として開発されているFlutter向けのMarkdownレンダラーです。

GitHub Flavored Markdown(GFM)を標準でサポートしており、Markdown形式の文字列をFlutterのWidgetとして表示できます。

この記事では、flutter_markdown_plus の基本的な使い方から、リンクやテーブル、コードブロック、スタイルのカスタマイズまで解説します。


flutter_markdown_plusとは?

flutter_markdown_plus は、Markdown形式のテキストをFlutterのWidgetとしてレンダリングするためのパッケージです。

内部ではDartの markdown パッケージを利用してMarkdownを解析し、その結果をFlutterのWidgetツリーとして表示します。

元々Flutter公式の flutter_markdown が存在していましたが、そのパッケージが終了したことを受け、Foresight Mobileによって継続的なメンテナンスが行われています。

主な特徴は以下の通りです。

  • GitHub Flavored Markdown対応
  • 見出し・太字・斜体対応
  • リスト対応
  • テーブル対応
  • タスクリスト対応
  • コードブロック対応
  • リンク対応
  • 画像表示対応
  • フットノート対応
  • 絵文字対応
  • テキスト選択対応
  • MarkdownStyleSheetによる詳細なスタイル設定
  • カスタムBuilder対応
  • Android / iOS / Web / macOS / Windows / Linux対応

FlutterアプリでMarkdownコンテンツを扱う場合に非常に使いやすいパッケージです。


インストール

まずはプロジェクトにパッケージを追加します。

flutter pub add flutter_markdown_plus

または pubspec.yaml に直接追加します。

dependencies:
  flutter_markdown_plus: ^1.0.12

その後、以下を実行します。

flutter pub get

最新版は記事執筆時点で 1.0.12 です。


基本的な使い方

まずはパッケージをインポートします。

import 'package:flutter_markdown_plus/flutter_markdown_plus.dart';

Markdownを表示するだけなら非常に簡単です。

const markdown = '''
# Flutter

これは **Markdown** で書かれた文章です。

- Flutter
- Dart
- Firebase
''';

Markdown(
  data: markdown,
)

これだけでMarkdownが解析され、Flutter上にリッチテキストとして表示されます。

通常の Text Widgetで表示する場合と違い、見出しや太字、リストなどが自動的に適切なWidgetへ変換されます。


MarkdownBodyを使う

Markdown Widgetは、スクロール可能なコンテナとしてMarkdownを表示します。

一方、既存のレイアウトの中にMarkdownを埋め込みたい場合は MarkdownBody が便利です。

MarkdownBody(
  data: '''
# Flutter

MarkdownBodyは、
既存のWidgetツリーにMarkdownを埋め込む場合に便利です。
''',
)

例えば、

SingleChildScrollView
    ↓
Column
    ↓
MarkdownBody

のような構成で利用できます。

MarkdownBody 自体はスクロールを管理しないため、親Widget側でスクロールを制御できます。


MarkdownとMarkdownBodyの違い

主に以下のように使い分けます。

Widget用途
MarkdownMarkdown専用のスクロールビューとして表示
MarkdownBody既存のレイアウトにMarkdownを埋め込む
MarkdownRawMaterialテーマを適用せずMarkdownを表示

例えば、記事ページ全体をMarkdownで表示するなら Markdown が向いています。

一方、商品詳細ページの説明文の一部だけMarkdownで表示する場合は MarkdownBody が使いやすいでしょう。

また、既存のScrollView内で Markdown を利用したい場合は、noScroll: true を指定することでスクロールを持たない形でレンダリングできます。


見出しを表示する

Markdownの見出しにも対応しています。

MarkdownBody(
  data: '''
# 見出し1

## 見出し2

### 見出し3
''',
)

Markdownの記法に合わせて見出しが自動的にスタイリングされます。


太字・斜体・取り消し線

一般的なMarkdown記法にも対応しています。

MarkdownBody(
  data: '''
**太字**

*斜体*

~~取り消し線~~
''',
)

GitHubで使われるMarkdownに近い記法をそのまま利用できます。


リストを表示する

箇条書きも簡単に表示できます。

MarkdownBody(
  data: '''
- Flutter
- Dart
- Firebase

1. プロジェクト作成
2. パッケージ追加
3. アプリ起動
''',
)

ネストされたリストにも対応しています。


タスクリスト

GitHubなどでよく使われるタスクリストも利用できます。

- [x] Flutterをインストール
- [x] プロジェクトを作成
- [ ] アプリを実装

Flutterアプリ上でもチェックボックス形式で表示できます。

ドキュメントやTODO管理機能などにも活用できます。


テーブルを表示する

Markdownのテーブルにも対応しています。

MarkdownBody(
  data: '''
| Package | Description |
|---|---|
| Flutter | UI Framework |
| Firebase | Backend |
| Dart | Programming Language |
''',
)

結果としてMarkdownのテーブルがFlutter上に表示されます。

テーブルの罫線やセルの配置、列幅などもカスタマイズできます。


コードブロックを表示する

技術系アプリやドキュメントアプリではコードブロックを表示したいケースがあります。

MarkdownBody(
  data: '''
```dart
void main() {
  print('Hello Flutter');
}

”’,
)


フェンス付きコードブロックに対応しているため、Markdown形式のコードをそのまま表示できます。

コードブロックは水平方向へのスクロールにも対応しているため、長いコードを扱う場合にも便利です。([pub.dev](https://pub.dev/packages/flutter_markdown_plus?utm_source=chatgpt.com))

---

## リンクをタップする

Markdown内のリンクは、タップ時の処理を自分で指定できます。

```dart
Markdown(
  data: '''
[Flutter公式サイト](https://flutter.dev)
''',
  onTapLink: (
    String text,
    String? href,
    String title,
  ) {
    if (href != null) {
      print(href);
    }
  },
)

実際にブラウザでURLを開きたい場合は、url_launcher などのパッケージと組み合わせることができます。

例えば、

onTapLink: (
  text,
  href,
  title,
) async {
  if (href != null) {
    await launchUrl(
      Uri.parse(href),
    );
  }
},

のように実装できます。

flutter_markdown_plus 自体がリンク先を自動的に開くのではなく、onTapLink でアプリ側が動作を決められる設計になっています。


画像を表示する

Markdownの画像記法にも対応しています。

![Flutter Logo](https://flutter.dev/assets/images/shared/brand/flutter/logo/flutter-lockup.png)

FlutterのWidgetとしてMarkdownを表示すると、画像もレンダリングされます。

対応している画像ソースは主に以下です。

  • http://
  • https://
  • ローカルファイル
  • アプリにバンドルしたAsset

Assetを利用する場合は、

resource:assets/images/flutter.png

のように指定できます。


テキスト選択を有効にする

Markdown内のテキストをユーザーが選択できるようにすることも可能です。

Markdown(
  data: markdown,
  selectable: true,
)

例えば、

  • 技術ドキュメント
  • AIチャット
  • ブログ記事
  • 利用規約

などで、文章をコピーしたい場合に便利です。


選択範囲の変更を検知する

テキスト選択が変更されたときは、onSelectionChanged を利用できます。

Markdown(
  data: markdown,
  selectable: true,
  onSelectionChanged: (
    text,
    selection,
    cause,
  ) {
    print(text);
  },
)

選択されたテキストを取得して、

  • コピー
  • 共有
  • 検索
  • AIへの送信

などの処理につなげることもできます。


選択メニューをカスタマイズする

selectable を有効にした場合、テキスト選択時のコンテキストメニューもカスタマイズできます。

最新バージョンでは contextMenuBuilder が追加されており、標準の選択ツールバーを変更したり、独自のメニューへ置き換えたりできます。

例えば、

コピー
共有
検索
AIに質問

といった独自の操作メニューを実装することも可能です。


MarkdownStyleSheetでデザインを変更する

Markdownの見た目は MarkdownStyleSheet でカスタマイズできます。

例えば、

MarkdownBody(
  data: markdown,
  styleSheet:
      MarkdownStyleSheet.fromTheme(
        Theme.of(context),
      ).copyWith(
        h1: const TextStyle(
          fontSize: 32,
          fontWeight: FontWeight.bold,
        ),
        h2: const TextStyle(
          fontSize: 24,
          fontWeight: FontWeight.bold,
        ),
        p: const TextStyle(
          fontSize: 16,
          height: 1.6,
        ),
      ),
)

のように指定できます。

見出しや本文だけでなく、

  • コード
  • 引用
  • リスト
  • テーブル
  • リンク

など、Markdownの各要素を細かくスタイリングできます。


ダークモード対応

MarkdownのスタイルをFlutterのThemeから生成できます。

MarkdownBody(
  data: markdown,
  styleSheet:
      MarkdownStyleSheet.fromTheme(
        Theme.of(context),
      ),
)

これにより、アプリのライトテーマ・ダークテーマに合わせてMarkdownの表示を変更できます。

また、blockquote(引用)のデフォルトスタイルもライトテーマ・ダークテーマに対応しています。


カスタムBuilderを利用する

より高度なカスタマイズを行いたい場合は、カスタムBuilderを利用できます。

Markdownの特定要素を自分でWidget化することで、

Markdown
    ↓
特定の要素を検出
    ↓
独自Widgetへ変換

といった処理が可能です。

例えば、

  • 独自のリンクカード
  • カスタム画像Widget
  • 特殊なタグ
  • 独自のUIコンポーネント

などをMarkdown内に組み込む用途に利用できます。


AIチャットとの相性が良い

最近では、生成AIのレスポンスをMarkdown形式で返すケースが増えています。

例えば、

AI
↓
Markdown形式のレスポンス
↓
flutter_markdown_plus
↓
Flutter Widget

という構成にできます。

AIの回答に、

  • 見出し
  • 太字
  • 箇条書き
  • コードブロック
  • テーブル

などが含まれていても、そのままリッチなUIとして表示できます。

AIチャットアプリやAIエージェントアプリをFlutterで開発する場合には、特に相性の良いパッケージです。


noScrollで既存のScrollViewに組み込む

通常の Markdown は自身でスクロールを管理します。

しかし、既に SingleChildScrollViewCustomScrollView などを利用している場合、Markdown側でもスクロールを持つと扱いづらいケースがあります。

その場合は noScroll が便利です。

Markdown(
  data: markdown,
  noScroll: true,
)

これにより、MarkdownをスクロールしないColumnとしてレイアウトできます。

例えば、

SingleChildScrollView
    ↓
Column
    ├── Header
    ├── Markdown
    └── Footer

のようなページを作る場合に便利です。


LaTeXを利用したい場合

技術ドキュメントやAIアプリでは、数式を表示したいケースもあります。

flutter_markdown_plus のエコシステムには、LaTeXレンダリング用の flutter_markdown_plus_latex パッケージも用意されています。

そのため、

Markdown
+
LaTeX

を組み合わせた表示を検討できます。

数式を多用するAIアプリや学習アプリなどでは便利な選択肢です。


GitHub Flavored Markdownに対応

flutter_markdown_plus はデフォルトでGitHub Flavored Markdown(GFM)を利用します。

そのため、

  • テーブル
  • タスクリスト
  • 取り消し線
  • フェンス付きコードブロック
  • 引用

など、GitHubで馴染みのあるMarkdown記法をそのまま利用できます。

GitHub上のREADMEや技術ドキュメントに近い形式のコンテンツをFlutterアプリで表示したい場合にも適しています。


HTMLには対応していない

注意点として、flutter_markdown_plusMarkdown内のInline HTMLには対応していません

例えば、

これは<br>改行です

のようなHTMLタグをMarkdown内に記述しても、WebブラウザのようにHTMLとして処理されるわけではありません。

これはFlutterがHTMLレンダラーではないためです。HTMLをそのままレンダリングする用途では、別のHTMLレンダリングパッケージを検討する必要があります。


主な機能まとめ

機能対応
Markdown表示
GitHub Flavored Markdown
見出し
太字・斜体
取り消し線
リスト
タスクリスト
テーブル
コードブロック
リンク
画像
フットノート
絵文字
テキスト選択
カスタムBuilder
カスタムスタイル
Android
iOS
Web
macOS
Windows
Linux
Inline HTML×

対応プラットフォームが幅広く、Flutterのマルチプラットフォーム開発にも利用できます。


メリット

flutter_markdownの後継として利用できる

既存の flutter_markdown に慣れている開発者にとって移行しやすいパッケージです。

Googleが開発していた元パッケージをベースに、継続的なメンテナンスが行われています。

Markdownの機能が豊富

基本的なMarkdownだけでなく、GFM、テーブル、タスクリスト、コードブロックなどにも対応しています。

カスタマイズ性が高い

MarkdownStyleSheet やカスタムBuilderを利用して、アプリのデザインに合わせた表示を実現できます。

AIアプリとの相性が良い

Markdown形式で返されるAIレスポンスを、そのままFlutter上でリッチに表示できます。

マルチプラットフォーム対応

Android、iOS、Web、macOS、Windows、Linuxに対応しています。


注意点

Inline HTMLは利用できない

WebブラウザのようにMarkdown内へHTMLを直接記述してレンダリングする用途には向いていません。

複雑なMarkdownは事前検証がおすすめ

Markdownの仕様には複数の方言や拡張が存在します。

flutter_markdown_plus はGFMをデフォルトで利用しますが、GitHubや他のMarkdownレンダラーと完全に同じ表示になるとは限りません。

外部APIやAIからMarkdownを受け取る場合は、実際のデータを使って表示を確認することをおすすめします。


まとめ

flutter_markdown_plus は、FlutterアプリでMarkdown形式のコンテンツをリッチなUIとして表示できる便利なパッケージです。

基本的なMarkdown記法だけでなく、

  • GitHub Flavored Markdown
  • テーブル
  • タスクリスト
  • コードブロック
  • リンク
  • 画像
  • テキスト選択
  • カスタムスタイル
  • カスタムBuilder

など、実際のアプリ開発で必要になる機能が幅広く用意されています。

特に、

  • AIチャットアプリ
  • AIエージェントアプリ
  • 技術ドキュメント
  • ブログアプリ
  • CMS
  • ニュースアプリ
  • ヘルプ・FAQ
  • 学習アプリ

などとの相性が良いでしょう。

また、flutter_markdown の後継として継続的にメンテナンスされている点も大きなポイントです。

FlutterアプリでMarkdownを表示する必要があるなら、まず候補に入れておきたいパッケージの一つです。

タイトルとURLをコピーしました