【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で修正した内容が反映されました。