首页 > 解决方案 > 如何在 Xamarin.Forms ios 中实现 UnifiedNative 广告

问题描述

我正在尝试在我的 xamarin.forms 应用程序中添加 UnifiedNative 广告。我在 Android 中成功实现了它们,但在 iOS 中遇到了困难。

对于 Android - 我创建了一个自定义渲染器和一个用于保存广告内容的 xml 布局。

对于 ios,我尝试遵循这个 - github.com/xamarin/GoogleApisForiOSComponents/blob/master/docs/Firebase/AdMob/ 但它不是很清楚并且仅在 Swift/Objective C 中提供帮助,我正在寻找 C#。

编辑 -

Xamarin.Forms

在 .xaml 中

 <adview:AdmobNativeAd HeightRequest="360"></adview:AdmobNativeAd>

AdView 类 -

 public class AdmobNativeAd : ContentView
    {
        public AdmobNativeAd()
        {
            this.HeightRequest = 360;
            this.Margin = new Thickness(8, 8, 8, 0);

            SetPlaceholderContent();
        }

        private void SetPlaceholderContent()
        {
            var placeholderGrid = new Grid();
            var placeHolderText = new Label
            {
                Text = "AD",
                FontSize = 48,
                FontAttributes = FontAttributes.Bold,
                TextColor = Color.White,
                Opacity = 0.3,
                VerticalOptions = new LayoutOptions(LayoutAlignment.Center, true),
                HorizontalOptions = new LayoutOptions(LayoutAlignment.Center, true)
            };

            placeholderGrid.Children.Add(placeHolderText);

            this.Content = placeholderGrid;
        }

    }

安卓实现——

[assembly: ExportRenderer(typeof(AdmobNativeAd), typeof(xxx.Droid.Services.NativeAd))]
namespace xxx.Droid.Services
{
    public class NativeAd : ViewRenderer
    {

        public NativeAd(Context context) : base(context) { }
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
        {
            base.OnElementChanged(e);

            if (Control == null)
            {
                var adLoader = new AdLoader.Builder(Context, "ca-app-pub-xxxxxxxxxxx/xxxxxxxx");

                var listener = new UnifiedNativeAdLoadedListener();
                listener.OnNativeAdLoaded += (s, ad) =>
                {
                    try
                    {
                        var root = new UnifiedNativeAdView(Context);
                        var inflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
                        var adView = (UnifiedNativeAdView)inflater.Inflate(Resource.Layout.ad_unified, root);

                        populateUnifiedNativeAdView(ad, adView);

                        SetNativeControl(adView);
                    }
                    catch
                    {

                    }
                };

                adLoader.ForUnifiedNativeAd(listener);
                var requestBuilder = new AdRequest.Builder();
                adLoader.Build().LoadAd(requestBuilder.Build());
            }
        }

        private void populateUnifiedNativeAdView(UnifiedNativeAd nativeAd, UnifiedNativeAdView adView)
        {
            adView.MediaView = adView.FindViewById<MediaView>(Resource.Id.ad_media);

            // Set other ad assets.
            adView.HeadlineView = adView.FindViewById<TextView>(Resource.Id.ad_headline);
            adView.BodyView = adView.FindViewById<TextView>(Resource.Id.ad_body);
            adView.CallToActionView = adView.FindViewById<TextView>(Resource.Id.ad_call_to_action);
            adView.IconView = adView.FindViewById<ImageView>(Resource.Id.ad_app_icon);
            adView.PriceView = adView.FindViewById<TextView>(Resource.Id.ad_price);
            adView.StarRatingView = adView.FindViewById<RatingBar>(Resource.Id.ad_stars);
            adView.StoreView = adView.FindViewById<TextView>(Resource.Id.ad_store);
            adView.AdvertiserView = adView.FindViewById<TextView>(Resource.Id.ad_advertiser);

            // The headline and mediaContent are guaranteed to be in every UnifiedNativeAd.
            ((TextView)adView.HeadlineView).Text = nativeAd.Headline;

            // These assets aren't guaranteed to be in every UnifiedNativeAd, so it's important to
            // check before trying to display them.
            if (nativeAd.Body == null)
            {
                adView.BodyView.Visibility = ViewStates.Invisible;
            }
            else
            {
                adView.BodyView.Visibility = ViewStates.Visible;
                ((TextView)adView.BodyView).Text = nativeAd.Body;
            }

            if (nativeAd.CallToAction == null)
            {
                adView.CallToActionView.Visibility = ViewStates.Invisible;
            }
            else
            {
                adView.CallToActionView.Visibility = ViewStates.Visible;
                ((Android.Widget.Button)adView.CallToActionView).Text = nativeAd.CallToAction;
            }

            if (nativeAd.Icon == null)
            {
                adView.IconView.Visibility = ViewStates.Gone;
            }
            else
            {
                ((ImageView)adView.IconView).SetImageDrawable(nativeAd.Icon.Drawable);
                adView.IconView.Visibility = ViewStates.Visible;
            }

            if (string.IsNullOrEmpty(nativeAd.Price))
            {
                adView.PriceView.Visibility = ViewStates.Gone;
            }
            else
            {
                adView.PriceView.Visibility = ViewStates.Visible;
                ((TextView)adView.PriceView).Text = nativeAd.Price;
            }

            if (nativeAd.Store == null)
            {
                adView.StoreView.Visibility = ViewStates.Invisible;
            }
            else
            {
                adView.StoreView.Visibility = ViewStates.Visible;
                ((TextView)adView.StoreView).Text = nativeAd.Store;
            }

            if (nativeAd.StarRating == null)
            {
                adView.StarRatingView.Visibility = ViewStates.Invisible;
            }
            else
            {
                ((RatingBar)adView.StarRatingView).Rating = nativeAd.StarRating.FloatValue();
                adView.StarRatingView.Visibility = ViewStates.Visible;
            }

            if (nativeAd.Advertiser == null)
            {
                adView.AdvertiserView.Visibility = ViewStates.Invisible;
            }
            else
            {
                ((TextView)adView.AdvertiserView).Text = nativeAd.Advertiser;
                adView.AdvertiserView.Visibility = ViewStates.Visible;
            }

            // This method tells the Google Mobile Ads SDK that you have finished populating your
            // native ad view with this native ad.
            adView.SetNativeAd(nativeAd);
        }
    }

    public class UnifiedNativeAdLoadedListener : AdListener, UnifiedNativeAd.IOnUnifiedNativeAdLoadedListener
    {
        public void OnUnifiedNativeAdLoaded(UnifiedNativeAd ad)
        {
            OnNativeAdLoaded?.Invoke(this, ad);
        }

        public EventHandler<UnifiedNativeAd> OnNativeAdLoaded { get; set; }
    }

}

用于处理接收到的广告内容的 XML -

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.formats.UnifiedNativeAdView android:hardwareAccelerated="false"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <android.support.v7.widget.CardView
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:cardPreventCornerOverlap="false"
        app:cardCornerRadius="12dp">
 
        <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:background="#FFFFFF">
 
            <AbsoluteLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1">
 
                <com.google.android.gms.ads.formats.MediaView
                  android:layout_width="match_parent"
                 android:layout_height="match_parent"
                    android:id="@+id/ad_media"/>
                
 
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="left"
                    android:text="Ad"
                    android:textColor="#FFFFFF"
                    android:background="#FFCC66"
                    android:textSize="14sp"
                    android:padding="4dp" />
            </AbsoluteLayout>
 
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:padding="5dp">
 
                <LinearLayout
                    android:layout_height="wrap_content"
                    android:layout_width="match_parent"
                    android:layout_weight="1"
                    android:orientation="vertical"
                    android:gravity="fill_horizontal">
 
                    <LinearLayout
                        android:layout_height="wrap_content"
                        android:layout_width="wrap_content"
                        android:orientation="horizontal">
 
                        <ImageView
                            android:id="@+id/ad_app_icon"
                            android:layout_width="40dp"
                            android:layout_height="40dp"
                            android:adjustViewBounds="true"
                            android:paddingBottom="5dp"
                            android:paddingEnd="5dp"
                            android:paddingRight="5dp"/>
 
                        <LinearLayout
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:orientation="vertical">
 
                            <TextView
                                android:id="@+id/ad_headline"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:textColor="#0000FF"
                                android:text="Join the dark side!"
                                android:textSize="16sp"
                                android:textStyle="bold" />
 
                            <LinearLayout
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"
                                android:orientation="horizontal">
 
                                <TextView
                                    android:id="@+id/ad_advertiser"
                                    android:layout_width="wrap_content"
                                    android:layout_height="wrap_content"
                                    android:gravity="bottom"
                                    android:textSize="14sp"
                                    android:text="Google"
                                    android:textColor="#222222"
                                    android:textStyle="bold"/>
 
                                <RatingBar
                                    android:id="@+id/ad_stars"
                                    style="?android:attr/ratingBarStyleSmall"
                                    android:layout_width="wrap_content"
                                    android:layout_height="wrap_content"
                                    android:isIndicator="true"
                                    android:numStars="5"
                                    android:stepSize="0.5"
                                    android:rating="4" />
                            </LinearLayout>
 
                        </LinearLayout>
                    </LinearLayout>
 
                    <TextView
                        android:textColor="#555555"
                        android:id="@+id/ad_body"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nis."
                        android:textSize="12sp" />
                </LinearLayout>
 
                <LinearLayout
                    android:layout_height="wrap_content"
                    android:layout_width="wrap_content"
                    android:orientation="vertical"
                    android:layout_gravity="center_vertical"
                    android:paddingLeft="5dp">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center_horizontal"
                        android:id="@+id/ad_store"
                           android:text="Google Play"
                        android:textColor="#222222"
                         android:textSize="12sp" />
 
                    <Button
                        android:id="@+id/ad_call_to_action"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:gravity="center"
                        android:layout_margin="0dp"
                        android:text="INSTALL"
                        android:textSize="12sp" />
 
                    <TextView
                        android:id="@+id/ad_price"
                        android:text="$ 3.49"
                        android:textColor="#222222"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center_horizontal"
                        android:textSize="12sp" />
 
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>
    </android.support.v7.widget.CardView>

</com.google.android.gms.ads.formats.UnifiedNativeAdView>

我已经将这篇文章推荐给 Android 实现 -

https://startdebugging.net/2019/09/admob-native-ads-in-xamarin-forms-android/

我在IOS中试过这个,到目前为止我的代码是这样的——

[assembly: ExportRenderer(typeof(AdmobNativeAd), typeof(AdMobNativeAdRenderer))]
namespace xxxx.iOS.Renderers
{
    public class AdMobNativeAdRenderer :  ViewRenderer<AdmobNativeAd, NativeExpressAdView>
    {
        NativeExpressAdView mAdView;
        bool viewOnScreen;

        // public AdMobNativeAdRenderer(Context context) : base() { }

        protected override void OnElementChanged(ElementChangedEventArgs<AdmobNativeAd> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement == null)
                return;

            if (e.OldElement == null)
            {
                CreateAdView(this);
            }
        }
                private void CreateAdView(AdMobNativeAdRenderer renderer)
                {

                    if (Element == null) return;

                    var loader = new AdLoader(
                       "ca-app-pub-xxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxx",
                        GetVisibleViewController(),
                        new AdLoaderAdType[] { AdLoaderAdType.UnifiedNative },
                        new AdLoaderOptions[] {
                    new NativeAdViewAdOptions {PreferredAdChoicesPosition = AdChoicesPosition.TopRightCorner}
                        });

                    var request = Request.GetDefaultRequest();
                    request.TestDevices = new string[] { Request.SimulatorId };

                   
                    if (adView == null) return;

                    try
                    {
                        loader.Delegate = new MyAdLoaderDelegate(renderer);
                        loader.LoadRequest(request);
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine(e.Message);
                    }

                    Debug.WriteLine("Loading: " + loader.IsLoading);
                }

                private UIViewController GetVisibleViewController()
                {
                    var windows = UIApplication.SharedApplication.Windows;
                    foreach (var window in windows)
                    {
                        if (window.RootViewController != null)
                        {
                            return window.RootViewController;
                        }
                    }
                    return null;
                }
            

我不知道如何为 IOS 创建类似于上述 xml doc 的 UI 并将其与委托链接。

另外,我想提一下我正在为这个项目使用 Visual Studio 2019 Windows。

标签: xamarin.formsxamarin.iosunifiednativeadview

解决方案


推荐阅读