🐈

普通の人なら踏まないComposeのWebViewの罠

2023/01/27に公開

とうとうJetpackComposeでWebViewを触る日が来てしまいました。
今回はAccompanistのWebViewをそのまま利用して問題なかったので、
カスタマイズなどせずに使っています。
ソースコードのコメントに「複雑なことやりたいなら参考にして勝手にやりな(僕訳)」と書かれていたので怖かったのですが、
特に困ることは少ない気がしています。
踏んだ罠だけだとつまらないので

  • ヘッダーの設定ってどうやるの?
  • JavaScriptを有効にしたい時は?
  • ページの表示状況を知るには?
    を紹介します

ヘッダーの設定ってどうやるの?

rememberWebViewStateurlと一緒にadditionalHttpHeadersがあるので、
Map形式で渡してください

JavaScriptを有効にしたい時は?

AccompanistのWebViewにてonCreatedコールバックが存在するので、そこでWebViewが受け取れます。
公式より引用

WebView(
    state = webViewState,
    onCreated = { it.settings.javaScriptEnabled = true }
)

ページの表示状況を知るには?

WebViewに渡すWebViewStateloadingStateを持っているので、
LaunchedEffectを使うなどして監視してあげればOKです。

踏んだ罠(リンクタップ時のイベント発火)

  • 実装を進めるにあたってonCreatedコールバックでWebViewが取得できることを知った
  • リンクをタップされた時と読み込み完了時にイベントを発火しないといけないと後から気付いた

その結果生み出したコードがこちら

webView.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
        // リンクタップ時の処理
    }

    override fun onPageFinished(view: WebView?, url: String?) {
        // 読み込み完了時の処理
    }
}

これだとどちらも動きません
正解はAccompanistのWebViewにあるclientAccompanistWebViewClientを指定してあげる必要があります。

WebView(
    ~~~
    client = object : AccompanistWebViewClient() {
        override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
            // リンクタップ時の処理
        }
    }
)

引数を見れば一瞬で気付けるので通常ならハマることなく対応できたと思いますが、
今回はたまたま、WebViewが取得できることを先に知ったことで古い知識が使えると思い込んだ事と、
ある程度実装が終わったタイミングで後からリンクタップ時と読み込み完了の処理を追加しようとしたことで、
たまたま踏んでしまいました。

WebViewを使う時は注意してください

最後に

バックキーの無効化やもっとカスタマイズしたい人向けの情報もあるので、
公式見ような!!

株式会社ゆめみ

Discussion