2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Accompanist の WebView Wrapper メモ2: 状態が画面回転に生き残らない

Posted at

Accompanist の WebView Wrapper を使って
Jetpack Compose で WebView を使うときのメモです。

👇 前回

このときのバージョンは com.google.accompanist:accompanist-webview:0.30.1 です。

今回のケースのサンプルコード

Google を WebView で表示する最小限のコードを書いてみます:

MyWebViewTest.kt
@Composable
private fun MyWebViewTest() {
    MyWebView(
        url = "https://www.google.co.jp/",
    )
}

@SuppressLint("SetJavaScriptEnabled")
@Composable
private fun MyWebView(
    url: String,
    modifier: Modifier = Modifier,
) {
    val state = rememberWebViewState(url = url)
    WebView(
        state = state,
        onCreated = { webView ->
            
            webView.settings.javaScriptEnabled = true
            webView.settings.domStorageEnabled = true
        },
        modifier = modifier,
    )
}

状態は安定版では画面回転に生き残らない

ページのナビゲーションの履歴や WebViewState が保持するページのタイトル, URL などの状態は画面回転を生き残りません:

accwebview-state-lost-by-rotation.gif

そのままだと状態が失われるのは
他の Jetpack Compose で使われる種々の State でも同じ話題がありますが、
WebView だと結構予想を裏切る感じで違和感があるかもしれません。

どうすればいいの?

今の安定版では rememberSaveable な API は用意されていないので、
必要な状態は onCreated, onDispose 時に自分で保持する必要があるということを意味しています。

これに関しては Issue が立てられていまして、ここで Workaround がコメントされていたりします:

そしてつい最近 v0.31.1-alpha で対応がされていて、
Saver が指定された rememberSaveableWebViewState という関数が追加されています:

MyWebViewTest.kt
+import androidx.compose.runtime.LaunchedEffect

-import com.google.accompanist.web.rememberWebViewState
+import com.google.accompanist.web.rememberSaveableWebViewState
+import com.google.accompanist.web.rememberWebViewNavigator

// 略…

-    val state = rememberWebViewState(url = url)
+    val state = rememberSaveableWebViewState()
+    val navigator = rememberWebViewNavigator()
+    LaunchedEffect(navigator) {
+        val bundle = state.viewState
+        if (bundle == null) {
+            navigator.loadUrl(url)
+        }
+    }
     WebView(
         state = state,
+        navigator = navigator,
         onCreated = { webView ->
             webView.settings.javaScriptEnabled = true
             webView.settings.domStorageEnabled = true

以前の状態がなければロードすることになるので、
LaunchedEffectWebViewState.viewStatenull か確認して WebViewNavigator#loadUrl をすることになるのがポイントですね。

これで画面回転しても状態が生き残るので違和感がない感じにできました:

acwebview-state-restored.gif

まだ安定版ではないですが、必要に応じてこれを使うことになるでしょう。
(Bundle の容量の話題はありつつ)


以上です。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?