I have an app that emulates ViewPager
behavior via HorizontalPager
. Each Pager has a WebView
, and the ViewPager
will release WebView
for pages that are far from the current page. What should I do in Jetpack Compose? It seems the composable should not be destroyed
This is expected behaviour. ViewPager
is a lazy view and it's not gonna store non visible views.
In clear Compose all you need to cache is scrolling position and some other state variables, and Compose will do that.
But when you're using AndroidView
, you had to manage it by yourself. I'm not sure if it's possible to retrieve WebView
scrolling position, but even if you can - the page still will be re-loaded.
A possible solution is storing WebViews
in a state like this:
val webViews = remember(LocalContext.current) { mutableStateMapOf<Int, WebView>() }
val state = rememberPagerState()
LaunchedEffect(state.currentPage) {
webViews.keys.forEach { key ->
val maxCacheDistance = 3
if (abs(key - state.currentPage) >= maxCacheDistance) {
webViews.remove(key)
println("webView $key deinited")
}
}
}
HorizontalPager(
count = 10,
state = state,
) { page ->
val url = "https://duckduckgo.com/?q=$page"
AndroidView(
factory = { context ->
webViews[page] ?: run {
WebView(context).also { webView ->
webView.settings.javaScriptEnabled = true
webViews[page] = webView
}
}
},
update = { webView ->
if (webView.url != url) {
webView.loadUrl(url)
}
},
modifier = Modifier.fillMaxSize()
)
}