webView上でFlutterとJavascriptのやり取りをする
概要
webView上からFlutterの処理を呼び出したいことがあったので、調査しました。
説明用にアプリを作成したので、このアプリを使って説明します。プログラムに関しては、以下のgithubをご参照くださいー。
webViewのパッケージ
FlutterにはwebViewのwidgetが標準で入ってないので、webViewを使う場合は外部パッケージが必要です。ということで、 flutter_inappwebview というパッケージを使いました。
公式のパッケージで webview_flutter というのがありますが、こちらはFlutterからJavascriptを呼び出すパターンに対応していないようでした。その場合は webview_flutter_plugin というパッケージを併せて使うことで対応できそうでしたが、ここ1年以上更新がなくサポートが微妙そうだったため、公式パッケージを使うのを断念しました。
検証用の画面
検証用の画面を下図に示します。
ButtonウィジェットとwebView上に実装したButtonがあるだけの簡単な画面です。
- Javascriptのアラートを表示を押すと、Javascriptのアラートが表示されます。
- Flutterのアラートを表示を押すと、AlertDialogが表示されます。
(どっちがどっちだかアラートの説明がややこしいですね・・)
検証用の画面
webViewの実装
まずは、webViewの実装です。
webViewのウィジェット(ここではInAppWebViewウィジェット)を以下のように書きます。
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を実行します。
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からの受け口を登録します。
webViewController.addJavaScriptHandler(
handlerName: 'showAlert', callback: _showAlert,
);
上記の場合は、showAlertというハンドラ名が来たら、_showAlert というメソッドを実行します。検証用に作成した _showAlert の中身は、AlertDialogを表示しているだけです。(githubをご参照ください。)
Javascript
次に、Javascript側でFlutterの処理をコールします。
<script>
function buttonAlertClick() {
window.flutter_inappwebview.callHandler('showAlert', '');
}
</script>
window.flutter_inappwebview.callHandler() を使います。第1引数にハンドラ名を入力し、第2引数にFlutter側に渡したいパラメータを入力します。(上記の場合は、特にないので空文字を入れています。)
動作確認
こちらもわかりにくいですが、ご了承ください(´;ω;`)
(webView上にある「Flutterのアラートを表示」ボタンをタップしています。)
HTMLのボタンからJavascriptを通してFlutterのアラートを表示
最後に
調査前は難しいかなと思いましたが、思ったよりも簡単に実装できました。ただ、動きに少しもっさり感があるので、その辺は少し調整が必要かもしれません。
Discussion