🌐

webView上でFlutterとJavascriptのやり取りをする

2022/09/16に公開

概要

webView上からFlutterの処理を呼び出したいことがあったので、調査しました。

説明用にアプリを作成したので、このアプリを使って説明します。プログラムに関しては、以下のgithubをご参照くださいー。

https://github.com/ponwink/flutter_javascript_on_webview

webViewのパッケージ

FlutterにはwebViewのwidgetが標準で入ってないので、webViewを使う場合は外部パッケージが必要です。ということで、 flutter_inappwebview というパッケージを使いました。

https://pub.dev/packages/flutter_inappwebview

公式のパッケージで webview_flutter というのがありますが、こちらはFlutterからJavascriptを呼び出すパターンに対応していないようでした。その場合は webview_flutter_plugin というパッケージを併せて使うことで対応できそうでしたが、ここ1年以上更新がなくサポートが微妙そうだったため、公式パッケージを使うのを断念しました。

検証用の画面

検証用の画面を下図に示します。
ButtonウィジェットとwebView上に実装したButtonがあるだけの簡単な画面です。

  • Javascriptのアラートを表示を押すと、Javascriptのアラートが表示されます。
  • Flutterのアラートを表示を押すと、AlertDialogが表示されます。

(どっちがどっちだかアラートの説明がややこしいですね・・)


検証用の画面

webViewの実装

まずは、webViewの実装です。
webViewのウィジェット(ここではInAppWebViewウィジェット)を以下のように書きます。

main.dart
InAppWebView(
  initialFile: 'assets/www/alert.html',
  onWebViewCreated: (InAppWebViewController webViewController) {
    _webViewController = webViewController;
    // Javascriptからの処理を登録
    webViewController.addJavaScriptHandler(
      handlerName: 'showAlert', callback: _showAlert,
    );
  },
)

initialFileは、最初に表示するhtmlファイルを設定します。ここでは、assetsに配置したhtmlファイルを読み込んでいますが、もちろんURLでも指定できます。
onWebViewCreatedは、ウィジェットが作成されたときの処理を実装します。JavascriptからのコールをFlutterで受け止める処理も書いてますが、後述します。

Flutter → Javascript

Flutterから、webViewで表示しているページのJavascriptを呼び出します。

Flutter

InAppWebView ウィジェットの onWebViewCreated で取得した webViewController を使って、javascriptを実行します。

alert_javascript.dart
webViewController.evaluateJavascript(source: 'alert("Hello, javascript!");');

InAppWebViewController クラスの evaluateJavascript() の source パラメータに javascript のコードを書くと、webView上でその javascript を実行します。

動作確認

動作はこんな感じです。
(動画を撮ったものの、どのボタンを押したかわかりにくいですね・・。「Javascriptのアラートを表示」ボタンをタップしています。)


FlutterのボタンからJavascriptのアラートを表示

Javascript → Flutter

今度は逆に、webViewで表示しているページのJavascriptからFlutterを呼び出します。

Flutter

まず、Flutter側でJavascriptからのコールを受け取る準備をします。
InAppWebView ウィジェットの onWebViewCreated で取得した webViewController を使って、Javascriptからの受け口を登録します。

main.dart
webViewController.addJavaScriptHandler(
  handlerName: 'showAlert', callback: _showAlert,
);

上記の場合は、showAlertというハンドラ名が来たら、_showAlert というメソッドを実行します。検証用に作成した _showAlert の中身は、AlertDialogを表示しているだけです。(githubをご参照ください。)

Javascript

次に、Javascript側でFlutterの処理をコールします。

alert.html
<script>
     function buttonAlertClick() {
         window.flutter_inappwebview.callHandler('showAlert', '');
     }
</script>

window.flutter_inappwebview.callHandler() を使います。第1引数にハンドラ名を入力し、第2引数にFlutter側に渡したいパラメータを入力します。(上記の場合は、特にないので空文字を入れています。)

動作確認

こちらもわかりにくいですが、ご了承ください(´;ω;`)
(webView上にある「Flutterのアラートを表示」ボタンをタップしています。)


HTMLのボタンからJavascriptを通してFlutterのアラートを表示

最後に

調査前は難しいかなと思いましたが、思ったよりも簡単に実装できました。ただ、動きに少しもっさり感があるので、その辺は少し調整が必要かもしれません。

Discussion