PR

[Flutter]WebViewで色々な操作をする方法(進む、戻る、リロード等)

Flutter

はじめに

前々回の記事でFlutterにWebViewを実装する方法を紹介しましたが、指定したURLにサクセスするだけの機能でした。

今回はWebViewを実装するに際によく使う進む、戻る、リロード等、もう少し詳しい紹介をしようと思います。

環境

  • Flutter 3.29.3
  • webview_flutter 4.11.0

実装方法

WebViewの実装方法は過去の記事で紹介しているのでそちらを参考にしてください。

サンプルコード

全体

まずは今回作成したサンプルの全体像をお見せします。

main.dart

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late WebViewController controller;
  bool canGoBack = false;
  bool canGoForward = false;

  @override
  void initState() {
    super.initState();

    controller =
        WebViewController()
          ..setJavaScriptMode(JavaScriptMode.unrestricted)
          ..setBackgroundColor(const Color(0x00000000))
          ..setNavigationDelegate(
            NavigationDelegate(
              onPageStarted: (url) {},
              onPageFinished: (url) async {
                canGoBack = await controller.canGoBack();
                canGoForward = await controller.canGoForward();
                setState(() {});
              },
              onWebResourceError: (error) {
                print('Error: ${error.description}');
              },
            ),
          )
          ..addJavaScriptChannel(
            "Print",
            onMessageReceived: (message) {
              print(message.message);
            },
          )
          ..loadRequest(Uri.parse('https://www.google.com/'));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('WebView'),
        actions: [
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: () async {
              await controller.reload();
            },
          ),
        ],
      ),
      body: SafeArea(child: WebViewWidget(controller: controller)),
      bottomNavigationBar: BottomAppBar(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            IconButton(
              icon: const Icon(Icons.arrow_back),
              onPressed:
                  canGoBack
                      ? () async {
                        if (await controller.canGoBack()) {
                          await controller.goBack();
                        }
                      }
                      : null,
            ),
            IconButton(
              icon: const Icon(Icons.arrow_forward),
              onPressed:
                  canGoForward
                      ? () async {
                        if (await controller.canGoForward()) {
                          await controller.goForward();
                        }
                      }
                      : null,
            ),
          ],
        ),
      ),
    );
  }
}

次からはよく使う機能を一つ一つ詳しく紹介していきます。

loadRequest

最初に表示するURLを指定します。

WebViewController()
          ..loadRequest(Uri.parse('https://www.google.com/'));

onPageStarted

この関数はWebViewがウェブページをロードし始めた際に呼ばれます。

今回のサンプルコードでは特に何もしていません。

        WebViewController()
          ..setNavigationDelegate(
            NavigationDelegate(
              onPageStarted: (url) {},
            ),
          )

onPageFinished

この関数はWebViewがウェブページのロードが終わった際に呼ばれます。

今回のサンプルコードでは進むと戻るボタンの表示制御のために利用しています。

        WebViewController()
          ..setNavigationDelegate(
            NavigationDelegate(
              onPageFinished: (url) async {
                canGoBack = await controller.canGoBack();
                canGoForward = await controller.canGoForward();
                setState(() {});
              },
            ),
          )

onWebResourceError

この関数はウェブリソースの読み込みに失敗した場合に呼ばれます。リソース(iframeや画像等)に限らず、あらゆるもので呼ばれるそうです。

今回のサンプルコードではデバッグ出力のみしています。

        WebViewController()
          ..setNavigationDelegate(
            NavigationDelegate(
              onWebResourceError: (error) {
                print('Error: ${error.description}');
              },
            ),
          )

javascriptMode

これを使うことでウェブページのJavascriptを制限することができます。ウェブページでJavascriptを使う必要があるならばunrestrictedに設定する必要があります。

javascriptMode備考
unrestricted無制限
disabled制限する(default)

今回のサンプルでは無制限に設定しています。

        WebViewController()
          ..setJavaScriptMode(JavaScriptMode.unrestricted)

addJavaScriptChannel

このパラメーターにハンドラーを登録しておくとウェブページからFlutter側のコードを実行することができるそうです。(動作未確認です)

        WebViewController()
          ..addJavaScriptChannel(
            "Print",
            onMessageReceived: (message) {
              print(message.message);
            },
          )

上記はFlutter(Dart)側のコードです。上記のコードを実行するためにウェブページに以下のようなJavascriptを埋め込み実行させるとFlutter側のコードが呼ばれ「Hello」とログに表示されます。

Print.postMessage('Hello');

WebViewController

最後にWebViewを操作するためのWebViewControllerを紹介します。

loadRequest

指定したURLをロードします。

currentUrl

現在表示されているURLを取得できます。

canGoBack

戻るページがあるかどうか確認できます。

canGoForward

進むページがあるかどうか確認できます。

goBack

前のページに戻ります。

goForward

ページを進ませます。

reload

現在のページをリロードします。

clearCache

WebViewで使用している全てのキャッシュを削除します。(iOSのWKWebViewはまだサポートされていないそうです。)

この関数を呼び出すとリロードも行われます。

実行結果

サンプルコードの実行結果です。

さいごに

WebViewの操作もそんなに難しくないので是非実装してみてください。

おすすめ参考書

コメント

タイトルとURLをコピーしました