You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Xamarin.Forms的Google AdMob控件页面加载时正常显示

Xamarin.Forms Google AdMob 广告需交互才显示问题修复

问题现象

当前基于 ViewModel 绑定 ContentPages 架构的 Xamarin.Forms 应用,其余功能(API拉取、页面导航、AdMob测试广告请求)均正常,但存在以下异常表现:

  • 页面初始加载时广告不渲染,仅当用户点击页面任意控件产生交互后广告才显示
  • About 页面存在完全相同的问题
  • 手动修改XAML中<ads:AdBanner />控件的任意布局属性(如HorizontalOptions)会立即触发广告显示
  • 跨页面导航后原页面已显示的广告会消失,再次修改对应页面AdBanner的XAML属性可恢复显示
    对应现象截图:
    页面初始加载无广告
    用户交互后广告正常展示
    修改XAML属性触发广告显示

根因说明

该问题是Xamarin.Forms自定义AdBanner渲染器的经典布局同步bug:AdMob原生广告加载完成后,没有主动向Xamarin.Forms布局系统传递尺寸变更通知,导致控件始终处于未测量、未排列的状态,仅当用户交互、XAML属性变更触发全局布局刷新时,才会完成广告控件的渲染流程。

修复步骤

1. 补全平台渲染器的加载完成回调逻辑

在Android、iOS项目的AdBanner自定义渲染器中,监听广告加载完成事件,在主线程强制触发原生控件布局,并同步尺寸到Forms层:
Android 渲染器代码示例:

// 绑定广告加载完成事件
adView.AdListener = new CustomAdListener();
// 自定义AdListener实现
public class CustomAdListener : AdListener
{
    public override void OnAdLoaded()
    {
        base.OnAdLoaded();
        // 所有UI操作切主线程执行
        Device.BeginInvokeOnMainThread(() =>
        {
            var nativeAdView = (AdView)Control;
            // 强制触发原生控件测量、布局
            nativeAdView.Measure(Android.Views.ViewGroup.LayoutParams.WrapContent, 
                Android.Views.ViewGroup.LayoutParams.WrapContent);
            nativeAdView.Layout(nativeAdView.Bounds);
            // 同步广告尺寸到Forms层控件,触发布局刷新
            var formsAdView = (AdBanner)Element;
            formsAdView.WidthRequest = nativeAdView.AdSize.Width;
            formsAdView.HeightRequest = nativeAdView.AdSize.Height;
        });
    }
}

iOS 渲染器代码示例:

adView.AdReceived += (sender, args) =>
{
    Device.BeginInvokeOnMainThread(() =>
    {
        var nativeAdView = (BannerView)Control;
        // 强制触发原生控件布局
        nativeAdView.SetNeedsLayout();
        nativeAdView.LayoutIfNeeded();
        // 同步尺寸到Forms层
        var formsAdView = (AdBanner)Element;
        formsAdView.WidthRequest = nativeAdView.Bounds.Width;
        formsAdView.HeightRequest = nativeAdView.Bounds.Height;
    });
};

2. 页面生命周期主动触发布局刷新

在所有承载AdBanner控件的ContentPage中,重写OnAppearing方法,页面显示时主动给广告控件赋值尺寸参数,避免跨页面导航返回后广告被布局系统标记为待刷新但未触发渲染:

// XAML中需给AdBanner控件配置x:Name="AdBanner"
protected override void OnAppearing()
{
    base.OnAppearing();
    // 根据平台设置对应标准Banner尺寸,可按需替换为你使用的广告尺寸
    if (Device.RuntimePlatform == Device.Android)
    {
        AdBanner.WidthRequest = AdSize.Banner.Width;
        AdBanner.HeightRequest = AdSize.Banner.Height;
    }
    else
    {
        AdBanner.WidthRequest = 320;
        AdBanner.HeightRequest = 50;
    }
    // 若广告未加载则主动触发加载
    if (!AdBanner.IsLoaded)
    {
        AdBanner.LoadAd();
    }
}

3. 布局结构优化

  • 不要将AdBanner控件放在ScrollView、ListView、CollectionView这类可滚动、带虚拟回收的容器内部,固定放在页面底部/顶部的非滚动布局区域
  • 不要给AdBanner设置HorizontalOptions="CenterAndExpand"这类动态拉伸的布局属性,广告控件需使用固定尺寸,避免布局系统无法计算控件位置导致跳过渲染

所有广告加载、UI修改逻辑必须在主线程执行,后台线程触发的回调不会触发Xamarin.Forms的布局刷新流程,会导致修复不生效。
修复完成后,每次页面加载、导航进入页面时,广告控件都会自动完成测量、排列、渲染流程,无需用户交互即可稳定显示,跨页面返回也不会出现广告消失的问题。

内容的提问来源于stack exchange,提问作者Drew Morgan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 17:48:18