🦔
Flutter WindowsでWebViewを使う方法①
はじめに
個人開発でwebview_windowsを使ってFlutter WindowsアプリでWebコンテンツを表示しているため、ノウハウを共有したいと思います。
一つの記事にまとめると少し長くなりそうなので、パートに分けて書きます。
今回の内容は、パッケージの導入からWebページの表示までの一連の作業になります。
システム要件
開発する前に、下記のシステム要件をすべて満たしているかを確認しましょう。
-
Windows 10 1809以上
-
WebView2 Runtime
-
Visual Studio 2019以上
-
Windows 11 SDK (10.0.22000.194以上)
Visual Studio Installer
のIndividual components
タブからWindows 11 SDK
を追加してインストールします。
-
導入
webview_windows
をpubspec.yaml
に追加します。
# pubspec.yaml
dependencies:
webview_windows: ^0.3.0
実装
URLでWebページを表示する
まずは必要最低限の機能を作りましょう。
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _webviewController = WebviewController();
void initState() {
super.initState();
_initWebView();
}
void dispose() {
// 不要なリソースを解放
_webviewController.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
body: Webview(_webviewController),
);
}
// WebviewControllerの初期化と初期設定を行う
Future<void> _initWebView() async {
await _webviewController.initialize();
await Future.wait([
_webviewController.setBackgroundColor(Colors.white),
_webviewController.setPopupWindowPolicy(WebviewPopupWindowPolicy.deny),
]);
await _webviewController.loadUrl('https://zenn.dev/topics/flutter');
// 設定を反映するため、WebViewを再描画させる
if (context.mounted) {
setState(() {});
}
}
}
これで、指定したURLのWebページを表示できるWebViewができました。
でも、まだまだ足りませんよね?
アドレスバーを作る
class _MyHomePageState extends State<MyHomePage> {
final _webviewController = WebviewController();
final _urlController = TextEditingController();
// true => 前のページが存在する(戻れる)
// false => 前のページが存在しない(戻れない)
var _canGoBack = false;
void initState() {
super.initState();
_initWebView();
}
void dispose() {
_webviewController.dispose();
_urlController.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
// controllerの初期化処理が完了するまで、インジケーターを表示する
body: _webviewController.value.isInitialized
? Column(
children: [
_addressBar,
Expanded(child: Webview(_webviewController)),
],
)
: const Center(child: CircularProgressIndicator()),
);
}
// アドレスバーの実装
Widget get _addressBar => Container(
margin: const EdgeInsets.all(4),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(8),
),
child: TextField(
// contorllerで現在表示中のWebページのURLを表示する
controller: _urlController,
decoration: InputDecoration(
icon: Padding(
padding: const EdgeInsets.only(left: 12),
child: IconButton(
// 前のページに戻れる・戻れないことによって、戻るボタンを有効・無効にする
onPressed: _canGoBack ? _webviewController.goBack : null,
icon: const Icon(Icons.arrow_back),
),
),
border: InputBorder.none,
),
// Enterキーを押すと、今入力しているURLを読み込む
onSubmitted: _webviewController.loadUrl,
),
);
Future<void> _initWebView() async {
await _webviewController.initialize();
await Future.wait([
_webviewController.setBackgroundColor(Colors.white),
_webviewController.setPopupWindowPolicy(WebviewPopupWindowPolicy.deny),
]);
// URLと閲覧履歴の変更を検知するためのリスナーを追加する
_webviewController.url.listen((url) => _urlController.text = url);
_webviewController.historyChanged.listen(
(event) => setState(() => _canGoBack = event.canGoBack),
);
await _webviewController.loadUrl('https://zenn.dev/topics/flutter');
if (context.mounted) {
setState(() {});
}
}
}
これで、シンプルなアドレスバーを作りましたね。
好きなURLを入力してWebページを表示したり前のページに戻ったりすることが可能になってます。
成果物
まとめ
今回はwebview_windowsを使ってWebコンテンツを表示するアプリを作成しました。
また、Streamを監視してリアルタイムでURLの表示や、指定ページの読み込み機能も実装しました。
WebViewとして十分な機能を備えているのではないでしょうか?
いや、まだまだ足りません!
次回はJavaScriptを中心に書く予定です。どうぞ楽しみにお待ちください。
Discussion