【Flutter】flutter_html パッケージの使い方について

【Flutter】flutter_html パッケージの使い方について

こんにちは、株式会社Pentagonでアプリ開発をしている日浦です。
今回は、flutter_html パッケージの使い方について、解説をします。
flutter_html パッケージを使うと、HTMLコンテンツをFlutterWidgetとして表示できます。

【こんな人に読んで欲しい】

HTMLコンテンツをFlutter widget treeにレンダリングしたい方

【この記事を読むメリット】

HTMLをFlutterWidgetとして表示する際、基本的なhtmlの内容とstyleの指定方法や制御について理解できます。

【結論】

htmlとcssなどの基礎知識は必要ですが、htmlデータを表示したりstyleを指定して表現も変更できます。
サポートされているタグやCSSが多いので使いやすいと思います。

パッケージには、widgetのレンダリングを細かく制御するためのカスタムAPIも用意されているので、必要に応じて挙動を決められるのも便利だと思いました。

目次

flutter_htmlとは?

HTMLコンテンツをFlutterWidgetとして表示できます。

以下がパッケージのリンクです。
https://pub.dev/packages/flutter_html

  • まずはpackageをinstall

pubspec.yaml に flutter_html を追記します。

dependencies:
  flutter:
    sdk: flutter
  flutter_html: ^2.2.1

サンプルコード

class _MyAppState extends State<MyApp> {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
         appBar: AppBar(
           title: const Text('flutter_html'),
         ),
         body: SingleChildScrollView(child: html)),
   );
 }
}

Widget html = Html(
 data: """
   <h1>Header 1</h1>
   <h2>Header 2</h2>
   <h3>Header 3</h3>
   <h3>List support:</h3>
     <ol>
           <li>List 1</li>
           <li>List 2</li>
           <li>List 3</li>
     </ol>
     <h3>Link support:</h3>
     <p>
       Linking to <a href='https://github.com'>websites</a> has never been easier.
     </p>
     <h3>Image support:</h3>
     <img alt='Google' src='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png' />
   """,
);

実行した画面

styleも指定できる

Widget html = Html(
 data: """
   <h1>Header 1</h1>
   <h2>Header 2</h2>
   <h3>Header 3</h3>
   <h3>List support:</h3>
     <ol>
           <li>List 1</li>
           <li>List 2</li>
           <li>List 3</li>
     </ol>
     <h3>Link support:</h3>
     <p>
       Linking to <a href='https://github.com'>websites</a> has never been easier.
     </p>
     <h3>Image support:</h3>
     <img alt='Google' src='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png' />
   """,
 style: {
   "h1": Style(color: Colors.red),
   "h2": Style(color: Colors.orange),
   "h3": Style(color: Colors.blueAccent),
   "li": Style(margin: const EdgeInsets.all(8)),
   "p": Style(fontWeight: FontWeight.bold),
 },
);

リンクや画像のタップ検知

リンクや画像タグがタップされた時、何をすべきかを定義できます。

onLinkTap: (url, _, __, ___) {
 print("Opening $url...");
},
onImageTap: (src, _, __, ___) {
 print(src);
},

インラインフレームについて

NavigationDelegateを使用して、特定のURLのロードをブロックまたは許可できます。

Widget html = Html(
 data: """
  <h3>YouTube iframe:</h3>
  <iframe src="https://google.com"></iframe>
  <h3>Google iframe:</h3>
  <iframe src="https://www.youtube.com/embed/tgbNymZ7vqY"></iframe>
  """,
 navigationDelegateForIframe: (NavigationRequest request) {
   if (request.url.contains("google.com/images")) {
     return NavigationDecision.prevent;
   } else {
     return NavigationDecision.navigate;
   }
 },
);

WebViewとは違うのか?

https://pub.dev/packages/webview_flutter
というものがありますが、webview_flutterはインラインブラウザビューを使って表示しますが、
flutter_html はFlutterのHTMLサブセットを直接レンダリングします。

WebViewでは、ChromeやSafariなどWebブラウザーのレンダリングエンジンを呼び出してHTML等で構成されたWebページを取得するため、ブラウザーでの表示とほぼ同等ですが、flutter_html を使うと、直接レンダリングするのでレンタリング速度にも差が出そうです。

実際に両方試してみたところ、簡単なhtmlではそこまで差は出ませんでしたが、webViewでは一度loadをする時間があるのでflutter_htmlを使った方が表示は早かったです。


まとめ

  • タグやstyleを指定してページを作成できます。styleの指定は Dartで指定するのと同じように書けるので指定しやすかったです。
  • 今回は直接htmlを書きましたが、apiで文字列として取得したhtmlタグなどの表示もできるので色々使えそうです。
  • htmlタグが詳しい方はtableViewなども簡単に作れて便利そうです。
  • コード編集中はhot reloadは反映されず、restartで修正した内容が反映されました。
採用情報はこちら
目次