Open4

Flutter Markdown Package を使ってみた

fenfen

使ってみた感じ初期設定では使いにくかったので Builder などをいろいろといじっていく

utils フォルダに新規ファイルを作成

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

class H1 extends StatelessWidget {
  const H1({super.key, required this.text});
  final String text;

  
  Widget build(BuildContext context) {
    return SelectableText.rich(
      TextSpan(
        text: text,
        style: const TextStyle(
          fontSize: 28,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}

class H2 extends StatelessWidget {
  const H2({super.key, required this.text});
  final String text;

  
  Widget build(BuildContext context) {
    return SelectableText.rich(
      TextSpan(
        text: text,
        style: const TextStyle(
          fontSize: 26,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}

class H3 extends StatelessWidget {
  const H3({super.key, required this.text});
  final String text;

  
  Widget build(BuildContext context) {
    return SelectableText.rich(
      TextSpan(
        text: text,
        style: const TextStyle(
          fontSize: 24,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}

class H4 extends StatelessWidget {
  const H4({super.key, required this.text});
  final String text;

  
  Widget build(BuildContext context) {
    return SelectableText.rich(
      TextSpan(
        text: text,
        style: const TextStyle(
          fontSize: 22,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}

class H5 extends StatelessWidget {
  const H5({super.key, required this.text});
  final String text;

  
  Widget build(BuildContext context) {
    return SelectableText.rich(
      TextSpan(
        text: text,
        style: const TextStyle(
          fontSize: 20,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}

class H6 extends StatelessWidget {
  const H6({super.key, required this.text});
  final String text;

  
  Widget build(BuildContext context) {
    return SelectableText.rich(
      TextSpan(
        text: text,
        style: const TextStyle(
          fontSize: 18,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}

ファイルは分けてますが一緒にしちゃってもよさそう

custom_builder.dart
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:markdown/markdown.dart' as md;

import 'markdown_md.dart';

class CustomHeaderH1Builder extends MarkdownElementBuilder {
  
  Widget visitText(md.Text text, TextStyle? preferredStyle) {
    return H1(text: text.text);
  }
}

class CustomHeaderH2Builder extends MarkdownElementBuilder {
  
  Widget visitText(md.Text text, TextStyle? preferredStyle) {
    return H2(text: text.text);
  }
}

class CustomHeaderH3Builder extends MarkdownElementBuilder {
  
  Widget visitText(md.Text text, TextStyle? preferredStyle) {
    return H3(text: text.text);
  }
}

class CustomHeaderH4Builder extends MarkdownElementBuilder {
  
  Widget visitText(md.Text text, TextStyle? preferredStyle) {
    return H4(text: text.text);
  }
}

class CustomHeaderH5Builder extends MarkdownElementBuilder {
  
  Widget visitText(md.Text text, TextStyle? preferredStyle) {
    return H5(text: text.text);
  }
}

class CustomHeaderH6Builder extends MarkdownElementBuilder {
  
  Widget visitText(md.Text text, TextStyle? preferredStyle) {
    return H6(text: text.text);
  }
}

fenfen
hoge_page.dart
/// Markdown
child: Markdown(
  selectable: true,
  builders: {
    'h1': CustomHeaderH1Builder(),
    'h2': CustomHeaderH2Builder(),
    'h3': CustomHeaderH3Builder(),
    'h4': CustomHeaderH4Builder(),
    'h5': CustomHeaderH5Builder(),
    'h6': CustomHeaderH6Builder(),
  },
  data: 'hogehoge.text',
  styleSheet:
    MarkdownStyleSheet.fromTheme(Theme.of(context))
       .copyWith(
       blockSpacing: 20,
       /// ここで躓き
       p: const TextStyle(
       fontSize: 20,
      ),
   ),
  onTapLink: (text, href, title) async {
    if (href != null) {
      await openFileNotifier.openFile(href);
    } else {
      debugPrint('href is null');
    }
  },
),

ここの実装で一番困ったことはpです。
Hyperlink を実装したいのですが一つ前の投稿で作成した builder のpバージョンを作ると Hyperlink を読み取ってくれません。(今の自分の実力では解決できませんでした。)

なので強引に stylesheet で fontsize を指定することでpのカスタムと Hyperlink の共存ができるようになりました。

もし、この記事を見た方でこの問題を builder で解決することができる方!
ご教授ください!!!(オチ)