AdManagerAdView 在 LazyColumn 中离开屏幕时不渲染广告图像

Kel*_*ell 6 adview android-jetpack-compose android-jetpack-compose-list lazycolumn

我将 AdManagerAdView 包装在 AndroidView 中,以便可以在 Jetpack Compose 中使用它。当我在 LazyColumn 中使用图像时,图像无法加载,并且 AdManagerAdView 尝试在可组合项出现在屏幕上之前加载图像。

如果我快速滚动到该元素,那么 LazyColumn 将其组合起来,并且在图像从广告服务器返回之前它就出现在屏幕上,它会按预期工作。

LazyColumn {
        items(5) {
            SomeOtherComposable(it)
        }

        item {
            AndroidView(
                modifier = Modifier
                    .width(300.dp)
                    .height(250.dp)
                    .background(Color.Green),
                factory = { context ->
                    val adView = AdManagerAdView(context)
                    adView.adSize = AdSize.MEDIUM_RECTANGLE
                    adView.adUnitId = adUnitId
                    adView.loadAd(Builder().build())
                    adView
                }
            )
        }

        items(5) {
            SomeOtherComposable(it)
        }
}
Run Code Online (Sandbox Code Playgroud)

出于演示目的...

@Composable
fun SomeOtherComposable(i: Int) {
    Text(
        text = "SomeOtherComposable $i",
        modifier = Modifier
            .fillMaxWidth()
            .height(320.dp)
            .background(Color.White)
    )
}
Run Code Online (Sandbox Code Playgroud)

如果在非延迟列或任何其他 Compose 布局中使用包装的 AdManagerAdView,这也可以正常工作。

This feels like a weird timing thing in LazyColumn that just happens to manifest when the Composable isn't on screen yet since using it in a regular Column works fine under the same scenario.

Has anyone experienced anything like this?

SOLVED See my answer below

Kel*_*ell 4

好吧,问题实际上是在AndroidView 完成布局传递之前调用 和factory{}update{}在我的重现步骤中,广告图像会返回并在测量宽度和高度之前添加到内部视图中。

解决方案是将加载调用延迟到布局传递之后,doOnLayout{}如下所示:

AndroidView(
        modifier = Modifier
            .width(300.dp)
            .height(250.dp)
            .background(Color.Green),
        factory = { context ->
            val adView = AdManagerAdView(context)
            adView.adSize = AdSize.MEDIUM_RECTANGLE
            adView
        },
        update = { adView ->
            adView.adUnitId = adUnitId
            adView.doOnLayout {
                adView.loadAd(Builder().build())
            }
        }
    )
Run Code Online (Sandbox Code Playgroud)