分享您对 Google 移动广告 SDK 的反馈!参加年度问卷调查

原生高级广告

展示 UnifiedNativeAd

加载原生广告时,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).
    ...

    // If the app is using a MediaView, it should be instantiated and assigned
    // to the mediaView property. This view is a little different in that the asset
    // is populated automatically, so there's one less step.
    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

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

点击处理

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

Java

.withAdListener(new AdListener() {
    @Override onAdClicked() {
      // Log the click event or other custom behavior.
    }
})

Kotlin

.withAdListener(object : AdListener() {
    override fun onAdClicked() {
      // Log the click event or other custom behavior.
    }
})

注册 MediaView

MediaView 是一个专门用于展示主媒体素材资源的 View。它具有以下行为:

  • 如果加载的广告具有视频素材资源,则会对视频进行缓冲并开始在 MediaView 内播放。
  • 如果加载的广告不包含视频素材资源,则会改为下载第一个图片素材资源,并将其放置在 MediaView 内。

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

Java

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

Kotlin

adView.mediaView = adView.findViewById(R.id.ad_media)

注册原生广告对象

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

Java

adView.setNativeAd(ad);

Kotlin

adView.setNativeAd(ad)

原生视频广告

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

为了简化视频的配置和展示,移动广告 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, "ca-app-pub-3940256099942544/2247696110")
        .forUnifiedNativeAd( ... )
        .withNativeAdOptions(adOptions)
        .build();

Kotlin

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

val adOptions = NativeAdOptions.Builder()
        .setVideoOptions(videoOptions)
        .build()

val adLoader = AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110")
        .forUnifiedNativeAd( ... )
        .withNativeAdOptions(adOptions)
        .build()

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

VideoController

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

Java

VideoController vc = myNativeAd.getVideoController();

Kotlin

val vc = myNativeAd.videoController

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

VideoController 提供以下视频状态查询方法:

  • hasVideoContent() - 如果广告中有视频素材资源,则此方法返回 true,否则返回 false。
  • getAspectRatio() - 此方法返回视频的宽高比(宽度/高度),如果没有视频素材资源,则返回零。

应用也可以使用 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()