WebViewを使ったアプリ内ブラウザを作る場合、伝統的にWebView内の「戻る」操作は以下のように実装されてきました。
override fun onBackPressed() {
if (webView.canGoBack()) {
webView.goBack()
} else {
super.onBackPressed()
}
}
WebViewのコンテンツが戻る操作を受け付ける場合は、WebViewにバック操作を行わせ、WebView内コンテンツが戻れない状態になったら、ネイティブのナビゲーションに利用し、最終的にアプリを終了させる操作につなげます。
しかし、onBackPressed
はAPI 33でDeprecatedとなりました。
これからは OnBackPressedCallback
を使って実装することが求められます。
ただ、onBackPressed
はバックキーが押されたときに処理をフックするべきかどうか判定できましたが、OnBackPressedCallback
はバックキーが押される前にフックするかどうかを指定する必要があります。
この実装方法に慣れていないと、どうすればいいんだ?とフリーズしてしまうかもしれません。
OnBackPressedCallbackを使ったWebViewの「戻る」操作
まずは、OnBackPressedCallbackを実装します。WebViewのgoBack()
を呼び出すだけです。コンストラクタ引数にはfalseを指定し、デフォルトで無効状態にしておきます。
private val onBackPressedCallback: OnBackPressedCallback =
object : OnBackPressedCallback(false) {
override fun handleOnBackPressed() {
webView.goBack()
}
}
そして、(Activityの場合)以下のように、onBackPressedDispatcherにコールバックを登録しておきます。
onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
onBackPressedCallbackは無効状態なのでこの時点ではバックキーが押されても、onBackPressedCallbackが呼び出されることはなく、ネイティブ側のナビゲーションが実行されます(素のAcitivtyならActivityが終了)
WebViewの「戻る」操作をハンドリングするためには、onBackPressedCallbackを、WebViewが戻れる状態になった時に有効にして、戻れない状態になった時に無効化する必要があります。
これを判定するには、WebViewClientにてdoUpdateVisitedHistory
をoverrideします。WebViewのヒストリーが変化した際に呼び出されるメソッドですね。ここで、canGoBack()
の結果に応じて、onBackPressedCallbackの有効・無効を設定します。
webView.webViewClient = object : WebViewClient() {
override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) {
onBackPressedCallback.isEnabled = webView.canGoBack()
}
}
これで、WebViewの「戻る」操作をOnBackPressedCallbackで実装することができました。
以上です。