I'm building a Jetpack Compose screen that has an AppBar at the top and a WebView below it using AndroidView.
- The problem is that the AppBar takes a noticeable moment to appear when the screen loads.
- It seems like the presence of AndroidView (with the WebView) causes this delay.
- When the AndroidView is removed AppBar loads instantly.
@Composable fun LicenseScreen( backgroundColor: Int, handleMenuEvent: (MenuEvent) -> Unit, ) { val context = LocalContext.current Column( verticalArrangement = Arrangement.Top, horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .fillMaxSize() .background( color = colorResource(id = backgroundColor), shape = RoundedCornerShape( topStart = 15.dp, topEnd = 15.dp, 0.dp, 0.dp, ), ), ) { AppBar( "Notice License", backgroundColor) { handleMenuEvent(TopMenuItemEvent.OnBackClicked) } val licenceUrl = "file:///android_asset/notice_license.html" AndroidView( modifier = Modifier.wrapContentSize(), factory = { WebView(context).apply { loadUrl(licenceUrl) } }, ) } }
❓ My Questions:
- Why does the AppBar render with a delay when AndroidView is present?
- Is there a way to ensure the AppBar renders immediately, regardless of the WebView loading?
I'm building a Jetpack Compose screen that has an AppBar at the top and a WebView below it using AndroidView.
- The problem is that the AppBar takes a noticeable moment to appear when the screen loads.
- It seems like the presence of AndroidView (with the WebView) causes this delay.
- When the AndroidView is removed AppBar loads instantly.
@Composable fun LicenseScreen( backgroundColor: Int, handleMenuEvent: (MenuEvent) -> Unit, ) { val context = LocalContext.current Column( verticalArrangement = Arrangement.Top, horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .fillMaxSize() .background( color = colorResource(id = backgroundColor), shape = RoundedCornerShape( topStart = 15.dp, topEnd = 15.dp, 0.dp, 0.dp, ), ), ) { AppBar( "Notice License", backgroundColor) { handleMenuEvent(TopMenuItemEvent.OnBackClicked) } val licenceUrl = "file:///android_asset/notice_license.html" AndroidView( modifier = Modifier.wrapContentSize(), factory = { WebView(context).apply { loadUrl(licenceUrl) } }, ) } }
❓ My Questions:
- Why does the AppBar render with a delay when AndroidView is present?
- Is there a way to ensure the AppBar renders immediately, regardless of the WebView loading?
1 Answer
Reset to default 0The performance of AndroidView
is not great and it delays the whole composition. The easiest workaround I found is to wrap your AndroidView
into a LazyColumn
like this:
LazyColumn {
item {
AndroidView(
modifier = Modifier.wrapContentSize(),
factory = {
WebView(context).apply {
loadUrl(licenceUrl)
}
},
)
}
}
WebView
. I'm not sure why, but wrapping theWebView
in aFrameLayout
seems to fix it. I got the suggestion from stackoverflow/a/79465237, but I'm not yet sure if it's just a fluke in my setup. I'll investigate further when I get a chance later. – Mike M. Commented Apr 1 at 19:38WebView
's rendering is kinda "bleeding" outside of its bounds, but it only draws content inside, so when it invalidates itself after everything else is done, it ends up erasing everything outside. I just happened to have come across this recently working a different issue, and the solution is to addgraphicsLayer { clip = true }
to theAndroidView
'sModifier
. That will contain its rendering to its own bounds, preventing it from clearing everything else, and your app bar should show immediately. – Mike M. Commented Apr 2 at 2:41