Xamarin 形成 AdMob 自适应横幅广告 Android
Xamarin Forms AdMob Adaptive Banner Ad Android
我想将 AdMob 自适应横幅广告添加到我的应用程序页面的底部,但无论我做什么我都无法让它正确显示。我加载广告没有问题(我的插页式广告也工作正常),但我永远无法让它自己正确定位。我已经尝试了上百万位代码和属性的组合,并查看了我在 Internet 上可以找到的所有内容,但无济于事。
我的代码分为三部分:
共享项目中的自定义视图,继承自Frameclass(尽管网上的一些指南说继承自View,但广告完全不可见,除非我继承自Frame)。
using Xamarin.Forms;
namespace MyApp.Views
{
public class AdAdaptiveBannerView : Frame
{
public AdAdaptiveBannerView()
{
}
}
}
Android 项目中的自定义渲染器。
using Android.Content;
using Android.Gms.Ads;
using Android.Widget;
using System;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(MyApp.Views.AdAdaptiveBannerView), typeof(MyApp.Droid.AdAdaptiveBanner_Droid))]
namespace MyApp.Droid
{
public class AdAdaptiveBanner_Droid : ViewRenderer<Views.AdAdaptiveBannerView, AdView>
{
public static AdView adView;
public AdAdaptiveBanner_Droid(Context context) : base(context)
{
}
private AdView CreateAdView()
{
adView = new AdView(Android.App.Application.Context)
{
AdUnitId = "ca-app-pub-3940256099942544/6300978111", //ca-app-pub-3940256099942544/6300978111 is a banner test unit.
LayoutParameters = new LinearLayout.LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent), //For Adaptive Banner.
AdSize = AdSize.GetCurrentOrientationAnchoredAdaptiveBannerAdSize(Android.App.Application.Context, (int)(DeviceDisplay.MainDisplayInfo.Width / DeviceDisplay.MainDisplayInfo.Density))
//LayoutParameters = new LinearLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.WrapContent), //For SmartBanner.
//AdSize = AdSize.SmartBanner
};
adView.AdListener = new ListeningRegular();
adView.LoadAd(new AdRequest.Builder().Build());
return adView;
}
protected override void OnElementChanged(ElementChangedEventArgs<Views.AdAdaptiveBannerView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null && Control == null) SetNativeControl(CreateAdView());
}
}
internal class ListeningRegular : AdListener
{
public override void OnAdLoaded()
{
Console.WriteLine("Ad has loaded.");
base.OnAdLoaded();
}
public override void OnAdClosed()
{
Console.WriteLine("Ad has closed.");
AdAdaptiveBanner_Droid.adView.Dispose();
AdAdaptiveBanner_Droid.adView = null;
AdAdaptiveBanner_Droid.adView.AdListener = null;
GC.Collect();
base.OnAdClosed();
}
}
}
以及共享项目中的内容页面 XAML(我将背景颜色设置为某种颜色,这样我可以更容易地看到发生了什么)。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-MyApp.Views"
x:Class="MyApp.Pages.Page1">
<ContentPage.Content>
<StackLayout>
<Grid VerticalOptions="EndAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<views:AdAdaptiveBannerView BackgroundColor="DeepSkyBlue" />
</Grid>
</StackLayout>
</ContentPage.Content>
</ContentPage>
正如我所说,这可以正常加载广告,但它总是会裁掉广告的底部。除了看起来很傻之外,Google 的政策明确禁止这样做。
它还会随机决定何时打开页面以填充屏幕宽度或仅占用标准横幅广告宽度,例如以下两张图片(取自三星 Galaxy S6 运行 Android 7).
和
我认为这可能是因为 GetCurrentOrientationAnchoredAdaptiveBannerAdSize 不知道设备的方向并且在纵向和横向之间随机选择,但如果我使用 GetLandscapeAnchoredAdaptiveBannerAdSize 和 GetPortraitAnchoredAdaptiveBannerAdSize 取决于 DeviceDisplay.MainDisplayInfo.Orientation 它仍然随机选择。
如果我放弃尝试使用自适应横幅而是使用智能横幅(通过取消注释上面第二段代码中的两行注释并注释掉上面的两行)它看起来同样糟糕,周围有一个奇怪的边框。
它还会随机选择要加载的广告尺寸(即看它说 'This is a XxY test ad' 的位置),尽管我认为这应该取决于屏幕宽度,因此应该始终相同。
我试过将它放入各种容器(例如上面代码中所示的网格),但什么也没有。这个 post 已经够长了;如果我描述我尝试过的所有内容,那将是 50 页。
很长一段时间以来,我的印象是它与填充有关,因为它继承自 Frame(其默认填充为 20),但没有填充的组合(将其设置为 0 会使广告完全消失)、边距、垂直选项、水平选项、行定义属性或任何有帮助的东西。
还有,我不知道如何让它对旋转的设备做出反应,所以这是另一个问题,因为当你旋转屏幕时它看起来不对(你可以只设置 AdSize 一次)。
有人能帮忙吗?
编辑:我刚刚尝试以编程方式而不是在 XAML 中添加横幅广告,结果完全相同。这太令人沮丧了。
经过几个小时的 faff,看来我找到了解决方案。我必须使用 getCurrentOrientationAnchoredAdaptiveBannerAdSize 方法背后的代码(感谢 @youssef mountassir 提供的代码)来设置内容页面中自适应横幅视图的高度请求。我不知道如何在渲染器中执行此操作。
它仍然偶尔会在顶部和底部有一条细黑带,但我怀疑测试广告有问题。
我真正想知道的是为什么我必须这样做,而其他人似乎都不必这样做。
回答我的第二个问题,即旋转设备时如何更新它,更直接。我以编程方式将广告视图添加到页面,然后当设备旋转时我将其替换为新的。
我想将 AdMob 自适应横幅广告添加到我的应用程序页面的底部,但无论我做什么我都无法让它正确显示。我加载广告没有问题(我的插页式广告也工作正常),但我永远无法让它自己正确定位。我已经尝试了上百万位代码和属性的组合,并查看了我在 Internet 上可以找到的所有内容,但无济于事。
我的代码分为三部分:
共享项目中的自定义视图,继承自Frameclass(尽管网上的一些指南说继承自View,但广告完全不可见,除非我继承自Frame)。
using Xamarin.Forms;
namespace MyApp.Views
{
public class AdAdaptiveBannerView : Frame
{
public AdAdaptiveBannerView()
{
}
}
}
Android 项目中的自定义渲染器。
using Android.Content;
using Android.Gms.Ads;
using Android.Widget;
using System;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(MyApp.Views.AdAdaptiveBannerView), typeof(MyApp.Droid.AdAdaptiveBanner_Droid))]
namespace MyApp.Droid
{
public class AdAdaptiveBanner_Droid : ViewRenderer<Views.AdAdaptiveBannerView, AdView>
{
public static AdView adView;
public AdAdaptiveBanner_Droid(Context context) : base(context)
{
}
private AdView CreateAdView()
{
adView = new AdView(Android.App.Application.Context)
{
AdUnitId = "ca-app-pub-3940256099942544/6300978111", //ca-app-pub-3940256099942544/6300978111 is a banner test unit.
LayoutParameters = new LinearLayout.LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent), //For Adaptive Banner.
AdSize = AdSize.GetCurrentOrientationAnchoredAdaptiveBannerAdSize(Android.App.Application.Context, (int)(DeviceDisplay.MainDisplayInfo.Width / DeviceDisplay.MainDisplayInfo.Density))
//LayoutParameters = new LinearLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.WrapContent), //For SmartBanner.
//AdSize = AdSize.SmartBanner
};
adView.AdListener = new ListeningRegular();
adView.LoadAd(new AdRequest.Builder().Build());
return adView;
}
protected override void OnElementChanged(ElementChangedEventArgs<Views.AdAdaptiveBannerView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null && Control == null) SetNativeControl(CreateAdView());
}
}
internal class ListeningRegular : AdListener
{
public override void OnAdLoaded()
{
Console.WriteLine("Ad has loaded.");
base.OnAdLoaded();
}
public override void OnAdClosed()
{
Console.WriteLine("Ad has closed.");
AdAdaptiveBanner_Droid.adView.Dispose();
AdAdaptiveBanner_Droid.adView = null;
AdAdaptiveBanner_Droid.adView.AdListener = null;
GC.Collect();
base.OnAdClosed();
}
}
}
以及共享项目中的内容页面 XAML(我将背景颜色设置为某种颜色,这样我可以更容易地看到发生了什么)。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-MyApp.Views"
x:Class="MyApp.Pages.Page1">
<ContentPage.Content>
<StackLayout>
<Grid VerticalOptions="EndAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<views:AdAdaptiveBannerView BackgroundColor="DeepSkyBlue" />
</Grid>
</StackLayout>
</ContentPage.Content>
</ContentPage>
正如我所说,这可以正常加载广告,但它总是会裁掉广告的底部。除了看起来很傻之外,Google 的政策明确禁止这样做。
它还会随机决定何时打开页面以填充屏幕宽度或仅占用标准横幅广告宽度,例如以下两张图片(取自三星 Galaxy S6 运行 Android 7).
和
我认为这可能是因为 GetCurrentOrientationAnchoredAdaptiveBannerAdSize 不知道设备的方向并且在纵向和横向之间随机选择,但如果我使用 GetLandscapeAnchoredAdaptiveBannerAdSize 和 GetPortraitAnchoredAdaptiveBannerAdSize 取决于 DeviceDisplay.MainDisplayInfo.Orientation 它仍然随机选择。
如果我放弃尝试使用自适应横幅而是使用智能横幅(通过取消注释上面第二段代码中的两行注释并注释掉上面的两行)它看起来同样糟糕,周围有一个奇怪的边框。
它还会随机选择要加载的广告尺寸(即看它说 'This is a XxY test ad' 的位置),尽管我认为这应该取决于屏幕宽度,因此应该始终相同。
我试过将它放入各种容器(例如上面代码中所示的网格),但什么也没有。这个 post 已经够长了;如果我描述我尝试过的所有内容,那将是 50 页。
很长一段时间以来,我的印象是它与填充有关,因为它继承自 Frame(其默认填充为 20),但没有填充的组合(将其设置为 0 会使广告完全消失)、边距、垂直选项、水平选项、行定义属性或任何有帮助的东西。
还有,我不知道如何让它对旋转的设备做出反应,所以这是另一个问题,因为当你旋转屏幕时它看起来不对(你可以只设置 AdSize 一次)。
有人能帮忙吗?
编辑:我刚刚尝试以编程方式而不是在 XAML 中添加横幅广告,结果完全相同。这太令人沮丧了。
经过几个小时的 faff,看来我找到了解决方案。我必须使用 getCurrentOrientationAnchoredAdaptiveBannerAdSize 方法背后的代码(感谢 @youssef mountassir 提供的代码)来设置内容页面中自适应横幅视图的高度请求。我不知道如何在渲染器中执行此操作。
它仍然偶尔会在顶部和底部有一条细黑带,但我怀疑测试广告有问题。
我真正想知道的是为什么我必须这样做,而其他人似乎都不必这样做。
回答我的第二个问题,即旋转设备时如何更新它,更直接。我以编程方式将广告视图添加到页面,然后当设备旋转时我将其替换为新的。