Display a UnifiedNativeAd
When a native ad loads, the Google Mobile Ads SDK invokes the listener for the corresponding ad format. Your app is then responsible for displaying the ad, though it doesn't necessarily have to do so immediately. To make displaying system-defined ad formats easier, the SDK offers some useful resources, as described below.
UnifiedNativeAdView
class
For the UnifiedNativeAd
format, there is the corresponding
UnifiedNativeAdView
class. This class is a
ViewGroup
that publishers should use as the root for the UnifiedNativeAd
. A
single UnifiedNativeAdView
corresponds to a single unified native ad.
Each view used to display that ad's assets (the ImageView
that displays the
screenshot asset, for instance) should be a child of the UnifiedNativeAdView
object.
The view hierarchy for a unified native ad that uses a
LinearLayout
to display its asset views might look like this:
<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>
Here is an example that creates a UnifiedNativeAdView
and
populates it with a 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) }
The ad view classes also provide methods used to register the view used for
each individual asset, and one to register the NativeAd
object itself.
Registering the views in this way allows the SDK to automatically handle tasks
such as:
- Recording clicks
- Recording impressions (when the first pixel is visible on the screen)
- Displaying the AdChoices overlay for native backfill creatives (currently limited to a select group of publishers)
AdChoices overlay
An AdChoices overlay is added as an ad view by the SDK when a backfill ad is returned. If your app uses native ads backfill, please leave space in your preferred corner of your native ad view for the automatically inserted AdChoices logo. Also, it's important that the AdChoices overlay be easily seen, so choose background colors and images appropriately. For more information on the overlay's appearance and function, refer to the programmatic native ads implementation guidelines.
Ad attribution for programmatic native ads
When displaying programmatic native ads, you must display an ad attribution to denote that the view is an advertisement. Learn more in our policy guidelines.
Code example
These are the steps for displaying a unified native ad:
- Create an instance of the
UnifiedNativeAdView
class. - For each ad asset to be displayed:
- Populate the asset view with the asset in the ad object.
- Register the asset view with the
ViewGroup
class.
- Register the
MediaView
if your native ad layout includes a large media asset.. - Register the ad object with the
ViewGroup
class.
Here is an example function that displays a 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) }
Let's take a look at the individual tasks:
Inflate the layout
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
In this example, we're inflating an XML layout that contains views for
displaying a unified native ad and then locating a reference to the
UnifiedNativeAdView
. Note that you could also reuse an existing
UnifiedNativeAdView
if there's one in your fragment or activity, or even
create an instance dynamically without using a layout file.
Populate and register the asset views
This sample code locates the view used to display the headline, sets its text
using the string asset provided by the ad object, and registers it with the
UnifiedNativeAdView
object:
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
This process of locating the view, setting its value, and registering it with the ad view class should be repeated for each of the assets provided by the native ad object that the app will display.
Click handling
Clicks on the ad view assets are handled by the SDK as long as you correctly populate and register the asset views, as discussed in the previous section.
Here is an example that uses an ad listener to observe click events:
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()
Register the MediaView
The MediaView
is a special View
designed to display the main media asset,
either video or image.
MediaView
can be defined in an XML layout or constructed
dynamically. It should be placed within the view hierarchy of a NativeAdView
,
just like any other asset view.
Apps using a MediaView
must register it with the NativeAdView
like
this:
Java
MediaView mediaView = adView.findViewById(R.id.ad_media); adView.setMediaView(mediaView);
Kotlin
adView.mediaView = adView.findViewById<MediaView>(R.id.ad_media)
As with all asset views, the media view needs to have its content populated.
This is done using the
mediaContent
property. The mediaContent
property of UnifiedNativeAd
contains
media content that can be passed to a MediaView
.
Here is a code snippet setting the media content for the media view:
Java
mediaView.setMediaContent(nativeAd.getMediaContent());
Kotlin
mediaView.mediaContent = nativeAd.mediaContent
Setting ImageScaleType
The MediaView
class has an ImageScaleType
property when displaying images.
If you want to change how an image is scaled in the MediaView
, set the
corresponding ImageView.ScaleType
using the setImageScaleType()
method of
the MediaView
.
For example, to fill the MediaView
when an image is displayed (ad has no
video):
Java
mediaView.setImageScaleType(ImageView.ScaleType.CENTER_CROP);
Kotlin
mediaView.imageScaleType = ImageView.ScaleType.CENTER_CROP
GitHub Sample
Our GitHub repository has the complete implementations for native custom rendering ads written in both Java and Kotlin.
Download Google Ad Manager Native ExampleMediaContent
The MediaContent
class holds the data related to the media content of the
native ad, which is displayed using the MediaView
class. When the MediaView
mediaContent
property is set with a MediaContent
instance:
- If a video asset is available, it's buffered and starts playing inside the
MediaView
. You can tell if a video asset is available by checkinghasVideoContent()
. - If the ad does not contain a video asset, the
mainImage
asset is downloaded and placed inside theMediaView
instead.
Register the native ad object
This final step registers the native ad object with the view that's responsible for displaying it:
Java
adView.setNativeAd(ad);
Kotlin
adView.setNativeAd(ad)
Native video
In addition to images, text, and numbers, some native ads contain video assets. Not every ad includes a video asset, and apps are not required to display them.
To simplify the configuration and display of video, the Mobile Ads SDK provides the following video-related classes:
VideoOptions
The VideoOptions
class allows apps to configure how native video assets should behave.
VideoOptions
objects should be assigned to a NativeAdOptions
object that's
used when constructing the AdLoader
:
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()
The VideoOptions.Builder
class currently offers one method,
setStartMuted()
,
which tells the SDK whether video assets should start in a muted state.
The default value is true
.
VideoController
The VideoController
class is used to retrieve information about video assets.
Apps can get a reference to the controller from a UnifiedNativeAd
object by
calling the
getVideoController()
method:
Java
VideoController vc = nativeAd.getVideoController();
Kotlin
val vc = myNativeAd.videoController
This method always returns a VideoController
object, even when no video asset
is present in the ad.
VideoController
offers the
hasVideoContent()
method, which returns true if the ad has a video asset, and false if it doesn't.
Apps can also use the
VideoController.VideoLifecycleCallbacks
class to get notifications when events occur in the lifecycle of a video asset:
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() } })
Destroy ad
When you are done showing your native ad, you should destroy it so that the ad is properly garbage collected.
Java
nativeAd.destroy();
Kotlin
nativeAd.destroy()
Test native ad code
Direct-sold ads
If you'd like to test out what direct-sold native ads are like, you can make use of this Ad Manager ad unit ID:
/6499/example/native
It's configured to serve sample app install and content ads, as well as a custom native ad format with the following assets:
- Headline (text)
- MainImage (image)
- Caption (text)
The template ID for the custom native ad format is 10063170
.
Native backfill ads
To test the behavior of native backfill ads, use this Ad Manager ad unit:
/6499/example/native-backfill
It serves sample app install and content ads that include the AdChoices overlay.