Native Ads

展示 UnifiedNativeAd

加载原生广告时,Google 移动广告 SDK 会调用相应广告格式的监听器。然后,就由您的应用负责展示广告了,尽管不一定要立即展示广告。为了更轻松地展示系统定义的广告格式,该 SDK 提供了一些实用资源,如下所述。

UnifiedNativeAdView

对于 UnifiedNativeAd 格式,有对应的 UnifiedNativeAdView 类。该类是一个 ViewGroup,发布商应将其用作 UnifiedNativeAd 的根。一个 UnifiedNativeAdView 对应于一个统一原生广告。凡是用于展示该广告素材资源的视图(例如,展示屏幕截图素材资源的 ImageView),均应是 UnifiedNativeAdView 对象的子对象。

对于使用 LinearLayout 展示素材资源视图的统一原生广告,其视图层次结构可能如下所示:

<com.google.android.gms.ads.formats.UnifiedNativeAdView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <LinearLayout
        android:orientation="vertical"
        ... >
            <LinearLayout
            android:orientation="horizontal"
            ... >
              <ImageView
               android:id="@+id/ad_app_icon"
               ... />
              <TextView
                android:id="@+id/ad_headline"
                ... />
             </LinearLayout>

             // Other assets such as image or media view, call to action, etc follow.
             ...
        </LinearLayout>
    </com.google.android.gms.ads.formats.UnifiedNativeAdView>
    

下面这个示例创建了一个 UnifiedNativeAdView,然后用 UnifiedNativeAd 填充该视图:

Java

    AdLoader.Builder builder = new AdLoader.Builder(this, "<your ad unit ID>")
        .forUnifiedNativeAd(new UnifiedNativeAd.OnUnifiedNativeAdLoadedListener() {
            @Override
            public void onUnifiedNativeAdLoaded(UnifiedNativeAd unifiedNativeAd) {
                // Assumes you have a placeholder FrameLayout in your View layout
                // (with id fl_adplaceholder) where the ad is to be placed.
                FrameLayout frameLayout =
                    findViewById(R.id.fl_adplaceholder);
                // Assumes that your ad layout is in a file call ad_unified.xml
                // in the res/layout folder
                UnifiedNativeAdView adView = (UnifiedNativeAdView) getLayoutInflater()
                    .inflate(R.layout.ad_unified, null);
                // This method sets the text, images and the native ad, etc into the ad
                // view.
                populateUnifiedNativeAdView(unifiedNativeAd, adView);
                frameLayout.removeAllViews();
                frameLayout.addView(adView);
            }
    });
    

Kotlin

    val builder = AdLoader.Builder(this, "<your ad unit ID>")
        .forUnifiedNativeAd { unifiedNativeAd ->
            // Assumes that your ad layout is in a file call ad_unified.xml
            // in the res/layout folder
            val adView = layoutInflater
                    .inflate(R.layout.ad_unified, null) as UnifiedNativeAdView
            // This method sets the text, images and the native ad, etc into the ad
            // view.
            populateUnifiedNativeAdView(unifiedNativeAd, adView)
            // Assumes you have a placeholder FrameLayout in your View layout
            // (with id ad_frame) where the ad is to be placed.
            ad_frame.removeAllViews()
            ad_frame.addView(adView)
        }
    

广告视图类还提供了注册每项素材资源所用视图时会用到的方法,并提供了一个用于注册 NativeAd 对象本身的方法。如果以这种方式注册视图,该 SDK 就可以自动处理诸如以下任务:

  • 记录点击次数
  • 记录展示次数(当第一个像素出现在屏幕上时)
  • 为原生补余广告素材(目前仅面向部分发布商提供)显示广告选择叠加层

广告选择叠加层

当返回补余广告时,该 SDK 会向广告视图添加广告选择叠加层。如果您的应用使用原生补余广告,请在原生广告视图中任选您喜欢的一角留出空间,用于展示自动插入的广告选择徽标。此外,广告选择叠加层一定要显眼易见,因此请选择适当的背景颜色和图片。如需详细了解叠加层的外观和功能,请参阅程序化原生广告植入指南

程序化原生广告的广告标示

在展示程序化原生广告时,您必须展示广告标示,以指明该视图是广告。请参阅我们的政策指南了解详情。

代码示例

以下是展示统一原生广告的步骤:

  1. 创建 UnifiedNativeAdView 类的实例。
  2. 对于要展示的每个广告素材资源:
    1. 使用广告对象中的素材资源填充素材资源视图。
    2. ViewGroup 类注册该素材资源视图。
  3. 如果您的原生广告布局包含大型媒体素材资源,请注册 MediaView
  4. ViewGroup 类注册广告对象。

以下是一个展示 UnifiedNativeAd 的示例函数:

Java

    private void displayUnifiedNativeAd(ViewGroup parent, UnifiedNativeAd ad) {

        // Inflate a layout and add it to the parent ViewGroup.
        LayoutInflater inflater = (LayoutInflater) parent.getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        UnifiedNativeAdView adView = (UnifiedNativeAdView) inflater
                .inflate(R.layout.my_ad_layout, parent);

        // Locate the view that will hold the headline, set its text, and call the
        // UnifiedNativeAdView's setHeadlineView method to register it.
        TextView headlineView = adView.findViewById<TextView>(R.id.ad_headline);
        headlineView.setText(ad.getHeadline());
        adView.setHeadlineView(headlineView);

        ...
        // Repeat the above process for the other assets in the UnifiedNativeAd
        // using additional view objects (Buttons, ImageViews, etc).
        ...

        // If the app is using a MediaView, it should be
        // instantiated and passed to setMediaView. This view is a little different
        // in that the asset is populated automatically, so there's one less step.
        MediaView mediaView = (MediaView) adView.findViewById(R.id.ad_media);
        adView.setMediaView(mediaView);

        // Call the UnifiedNativeAdView's setNativeAd method to register the
        // NativeAdObject.
        adView.setNativeAd(ad);

        // Ensure that the parent view doesn't already contain an ad view.
        parent.removeAllViews();

        // Place the AdView into the parent.
        parent.addView(adView);
    }
    

Kotlin

    fun displayUnifiedNativeAd(parent: ViewGroup, ad: UnifiedNativeAd) {

        // Inflate a layout and add it to the parent ViewGroup.
        val inflater = parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)
                as LayoutInflater
        val adView = inflater.inflate(R.layout.my_ad_layout, parent) as UnifiedNativeAdView

        // Locate the view that will hold the headline, set its text, and use the
        // UnifiedNativeAdView's headlineView property to register it.
        val headlineView = adView.findViewById<TextView>(R.id.ad_headline)
        headlineView.text = ad.headline
        adView.headlineView = headlineView

        ...
        // Repeat the above process for the other assets in the UnifiedNativeAd using
        // additional view objects (Buttons, ImageViews, etc).
        ...

        val mediaView = adView.findViewById<MediaView>(R.id.ad_media)
        adView.mediaView = mediaView

        // Call the UnifiedNativeAdView's setNativeAd method to register the
        // NativeAdObject.
        adView.setNativeAd(ad)

        // Ensure that the parent view doesn't already contain an ad view.
        parent.removeAllViews()

        // Place the AdView into the parent.
        parent.addView(adView)
    }

让我们来看看各项具体任务:

填充布局

Java

    LayoutInflater inflater = (LayoutInflater) parent.getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    UnifiedNativeAdView adView = (UnifiedNativeAdView) inflater
            .inflate(R.layout.my_ad_layout, parent);
    

Kotlin

    val inflater = parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)
            as LayoutInflater
    val adView = inflater.inflate(R.layout.my_ad_layout, parent) as UnifiedNativeAdView
    

在本示例中,我们要填充一个 XML 布局(该布局包含的视图用于展示统一原生广告),然后找到对 UnifiedNativeAdView 的引用。请注意,如果您的片段或活动中有现成的 UnifiedNativeAdView,也可以重复使用它;您甚至可以在不使用布局文件的情况下动态创建一个实例。

填充和注册素材资源视图

下面的示例代码会找到用于显示标题的视图,使用广告对象所提供的字符串素材资源设置视图的文字,然后向 UnifiedNativeAdView 对象注册该视图:

Java

    TextView headlineView = adView.findViewById<TextView>(R.id.ad_headline);
    headlineView.setText(ad.getHeadline());
    adView.setHeadlineView(headlineView);
    

Kotlin

    val headlineView = adView.findViewById<TextView>(R.id.ad_headline)
    headlineView.text = ad.headline
    adView.headlineView = headlineView
    

对于应用要展示的由原生广告对象所提供的每项素材资源,都应为其重复上述过程,即找到相应视图、设置其值并向广告视图类注册它。

点击处理

只要您按上一部分所述正确填充和注册了素材资源视图,该 SDK 就会处理广告视图素材资源获得的点击。

以下是一个使用广告监听器观察点击事件的示例:

Java

    AdLoader adLoader = new AdLoader.Builder(context, "/6499/example/native")
        ...
        .withAdListener(new AdListener() {
            @Override
            public void onAdFailedToLoad(int errorCode) {
                // Handle the failure by logging, altering the UI, and so on.
            }
            @Override
            public void onAdClicked() {
                // Log the click event or other custom behavior.
            }
        })
        .build();
    

Kotlin

    val adLoader = AdLoader.Builder(this, "/6499/example/native")
        ...
        .withAdListener(object : AdListener() {
            override fun onAdFailedToLoad(errorCode: Int) {
                // Handle the failure by logging, altering the UI, and so on.
            }
        })
        .build()
    

注册 MediaView

MediaView 是一个专门用于展示主媒体素材资源(视频或图片)的 View

MediaView 可以在 XML 布局中定义,也可以动态构建。就像所有其他素材资源视图一样,它应该放在 NativeAdView 的视图层次结构中。对于使用 MediaView 的应用,必须向 NativeAdView 注册它,如下所示:

Java

    MediaView mediaView = adView.findViewById(R.id.ad_media);
    adView.setMediaView(mediaView);
    

Kotlin

    adView.mediaView = adView.findViewById<MediaView>(R.id.ad_media)
    

与所有素材资源视图一样,媒体视图也需要填充内容,这通过使用 mediaContent 属性来完成。UnifiedNativeAdmediaContent 属性包含可传递到 MediaView媒体内容

以下代码段用于为媒体视图设置媒体内容:

Java

    mediaView.setMediaContent(nativeAd.getMediaContent());
    

Kotlin

    mediaView.mediaContent = nativeAd.mediaContent
    

设置 ImageScaleType

MediaView 类在显示图片时具有 ImageScaleType 属性。如果您想在 MediaView 中更改图片的缩放方式,请使用 MediaViewsetImageScaleType() 方法设置相应的 ImageView.ScaleType

例如,要在图片显示时填充 MediaView(广告中不包含视频),请使用以下代码:

Java

    mediaView.setImageScaleType(ImageView.ScaleType.CENTER_CROP);
    

Kotlin

    mediaView.imageScaleType = ImageView.ScaleType.CENTER_CROP
    

GitHub 示例

我们的 GitHub 代码库包含以 Java 和 Kotlin 编写的原生自定义呈现广告的完整实现方案。

下载 Google Ad Manager 原生广告示例

MediaContent

MediaContent 类包含与原生广告的媒体内容相关的数据,媒体内容则通过 MediaView 类展示。使用 MediaContent 实例设置 MediaView mediaContent 属性时:

  • 如果广告有视频素材资源可用,则系统会对其进行缓冲,并开始在 MediaView 内播放。您可以通过检查 hasVideoContent() 来判断是否有视频素材资源可用。
  • 如果广告不包含视频素材资源,则会改为下载 mainImage 素材资源,并将其放置在 MediaView 内。

注册原生广告对象

这是最后一步,也就是向负责显示原生广告对象的视图注册该对象:

Java

    adView.setNativeAd(ad);
    

Kotlin

    adView.setNativeAd(ad)
    

原生视频广告

除了图片、文字和数字外,有些原生广告会包含视频素材资源。但不是每个广告都会包含视频素材资源,相关应用也并非一定要展示这些资源。

为了简化视频的配置和展示,Google 移动广告 SDK 提供了与视频相关的以下类:

VideoOptions

通过 VideoOptions 类,您可以为应用配置原生视频素材资源的行为方式。VideoOptions 对象应该分配给构建 AdLoader 时使用的 NativeAdOptions 对象:

Java

    VideoOptions videoOptions = new VideoOptions.Builder()
            .setStartMuted(false)
            .build();

    NativeAdOptions adOptions = new NativeAdOptions.Builder()
            .setVideoOptions(videoOptions)
            .build();

    AdLoader adLoader = new AdLoader.Builder(this, "/6499/example/native")
            .forUnifiedNativeAd( ... )
            .withNativeAdOptions(adOptions)
            .build();
    

Kotlin

    val videoOptions = VideoOptions.Builder()
            .setStartMuted(false)
            .build()

    val adOptions = NativeAdOptions.Builder()
            .setVideoOptions(videoOptions)
            .build()
    val adLoader = AdLoader.Builder(this, "/6499/example/native")
            .forUnifiedNativeAd( ... )
            .withNativeAdOptions(adOptions)
            .build()
    

VideoOptions.Builder 类目前提供了 setStartMuted() 方法,用于指示该 SDK 是否应该在静音状态下开始播放视频素材资源。默认值为 true

VideoController

VideoController 类用于获取有关视频素材资源的信息。通过调用 getVideoController() 方法,应用可以从 UnifiedNativeAd 对象获得对该控制器的引用:

Java

    VideoController vc = nativeAd.getVideoController();
    

Kotlin

    val vc = myNativeAd.videoController
    

即使广告中没有视频素材资源,此方法也会始终返回 VideoController 对象。

VideoController 提供 hasVideoContent() 方法;如果广告中有视频素材资源,则该方法返回 true,否则返回 false。

应用也可以使用 VideoController.VideoLifecycleCallbacks 类,在视频素材资源生命周期内发生事件时接收通知:

Java

    VideoController vc = nativeAd.getVideoController();

    vc.setVideoLifecycleCallbacks(new VideoController.VideoLifecycleCallbacks() {
        public void onVideoEnd() {
            // Here apps can take action knowing video playback is finished.
            // It's always a good idea to wait for playback to complete before
            // replacing or refreshing a native ad, for example.
            super.onVideoEnd();
        }
    });
    

Kotlin

    val vc = nativeAd.videoController

    vc.setVideoLifecycleCallbacks(object : VideoController.VideoLifecycleCallbacks() {
        override fun onVideoEnd() {
            // Here apps can take action knowing video playback is finished.
            // It's always a good idea to wait for playback to complete before
            // replacing or refreshing a native ad, for example.
            super.onVideoEnd()
        }
    })
    

销毁广告

当完成原生广告展示后,您应该将其销毁,以便系统正确地对广告进行垃圾回收处理。

Java

    nativeAd.destroy();
    

Kotlin

    nativeAd.destroy()
    

测试原生广告代码

直销广告

如果您想测试直销原生广告的呈现效果,可以使用此 Ad Manager 广告单元 ID:

/6499/example/native
    

它已配置为投放示例应用安装广告、示例内容广告以及包含以下素材资源的自定义原生广告格式:

  • 标题(文字)
  • 主图(图片)
  • 图片说明(文字)

自定义原生广告格式的模板 ID 为 10063170

原生补余广告

要测试原生补余广告的行为,请使用此 Ad Manager 广告单元:

/6499/example/native-backfill
    

它投放包含广告选择叠加层的示例应用安装广告和内容广告。