Admanageradview在屏幕上屏幕上的屏幕上的AD图像不呈现

发布于 2025-01-17 21:53:01 字数 1391 浏览 0 评论 0原文

我将 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)
        }
}

出于演示目的...

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

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

这感觉就像 LazyColumn 中的一个奇怪的计时问题,当可组合项尚未出现在屏幕上时,它恰好会显现出来,因为在相同的场景下,在常规列中使用它可以正常工作。

有人经历过这样的事情吗?

已解决 请参阅下面我的回答

I am wrapping an AdManagerAdView in an AndroidView so I can use it in Jetpack Compose. The image fails to load when I use it in a LazyColumn AND the AdManagerAdView tries to load the image before the composable is on screen.

If I scroll quickly to that element, so LazyColumn composes it AND it is on screen before the image comes back from the ad server, it works as expected.

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)
        }
}

For demo purposes...

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

This also works fine if the wrapped AdManagerAdView is used in a non-lazy Column or any other Compose layout.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

污味仙女 2025-01-24 21:53:01

好吧,问题实际上是在 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())
            }
        }
    )

Ok, the issue is actually that both factory{} and update{} are called before the AndroidView has gone through the layout pass. In my steps to reproduce, the ad image is coming back and being added to the internal view before it has a measured width and height.

The solution is to delay that load call until after the layout pass using doOnLayout{} like so:

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())
            }
        }
    )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文