🦔

Flutter WindowsでWebViewを使う方法①

2023/09/15に公開

はじめに

個人開発でwebview_windowsを使ってFlutter WindowsアプリでWebコンテンツを表示しているため、ノウハウを共有したいと思います。

一つの記事にまとめると少し長くなりそうなので、パートに分けて書きます。

今回の内容は、パッケージの導入からWebページの表示までの一連の作業になります。

システム要件

開発する前に、下記のシステム要件をすべて満たしているかを確認しましょう。

  • Windows 10 1809以上

  • WebView2 Runtime

    ダウンロード

  • Visual Studio 2019以上

    インストール手順

    • Windows 11 SDK (10.0.22000.194以上)

      Visual Studio InstallerIndividual componentsタブからWindows 11 SDKを追加してインストールします。

導入

webview_windowspubspec.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

まとめ

今回はwebview_windowsを使ってWebコンテンツを表示するアプリを作成しました。

また、Streamを監視してリアルタイムでURLの表示や、指定ページの読み込み機能も実装しました。

WebViewとして十分な機能を備えているのではないでしょうか?

いや、まだまだ足りません!

次回はJavaScriptを中心に書く予定です。どうぞ楽しみにお待ちください。

GitHubで編集を提案

Discussion