最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

android - AppBar loads with delay when using AndroidView with WebView in Jetpack Compose - Stack Overflow

programmeradmin5浏览0评论

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?
Share Improve this question asked Apr 1 at 7:32 DraxDrax 692 silver badges6 bronze badges 2
  • In my quick tests, it's even worse, and the app bar doesn't appear at all until you scroll the WebView. I'm not sure why, but wrapping the WebView in a FrameLayout 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:38
  • OK, I think I know what the problem is, in broad strokes, anyway. The WebView'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 add graphicsLayer { clip = true } to the AndroidView's Modifier. 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
Add a comment  | 

1 Answer 1

Reset to default 0

The 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)
                }
            },
        )
    }
}
发布评论

评论列表(0)

  1. 暂无评论