Native advanced

Select platform: Android iOS

When a native ad loads, 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.

Define the NativeAdView class

Define a NativeAdView class. This class is a ViewGroup class and is the top level container for a NativeAdView class. Each native ad view contains native ad assets, such as the MediaView view element or the Title view element, which must be a child of the NativeAdView object.

XML Layout

Add a XML NativeAdView to your project:

 <com.google.android.gms.ads.nativead.NativeAdView  
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>  
<!--Add  
remaining  
assets  
such  
as  
the  
image  
and  
media  
view.-->  
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView> 

Jetpack Compose

Include JetpackComposeDemo/compose-util module which includes helpers for composing the NativeAdView and its assets.

Using the compose-util module, compose a NativeAdView :

   
 import 
  
 com.google.android.gms.compose_util.NativeAdAttribution 
  
 import 
  
 com.google.android.gms.compose_util.NativeAdView 
  
 @Composable 
  
 /** Display a native ad with a user defined template. */ 
  
 fun 
  
 DisplayNativeAdView 
 ( 
 nativeAd 
 : 
  
 NativeAd 
 ) 
  
 { 
  
 NativeAdView 
  
 { 
  
 // Display the ad attribution. 
  
 NativeAdAttribution 
 ( 
 text 
  
 = 
  
 context 
 . 
 getString 
 ( 
 "Ad" 
 )) 
  
 // Add remaining assets such as the image and media view. 
  
 } 
  
 } 
 

Handle the loaded native ad

When a native ad loads, handle the callback event, inflate the native ad view, and add it to the view hierarchy:

Java

  AdLoader 
 . 
 Builder 
  
 builder 
  
 = 
  
 new 
  
 AdLoader 
 . 
 Builder 
 ( 
 this 
 , 
  
 "/21775744923/example/native" 
 ) 
  
 . 
 forNativeAd 
 ( 
 new 
  
 NativeAd 
 . 
 OnNativeAdLoadedListener 
 () 
  
 { 
  
 @Override 
  
 public 
  
 void 
  
 onNativeAdLoaded 
 ( 
 NativeAd 
  
 nativeAd 
 ) 
  
 { 
  
 // 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 native_ad_layout.xml 
  
 // in the res/layout folder 
  
 NativeAdView 
  
 adView 
  
 = 
  
 ( 
 NativeAdView 
 ) 
  
 getLayoutInflater 
 () 
  
 . 
 inflate 
 ( 
 R 
 . 
 layout 
 . 
 native_ad_layout 
 , 
  
 null 
 ); 
  
 // This method sets the assets into the ad view. 
  
 displayNativeAd 
 ( 
 nativeAd 
 , 
  
 adView 
 ); 
  
 frameLayout 
 . 
 removeAllViews 
 (); 
  
 frameLayout 
 . 
 addView 
 ( 
 adView 
 ); 
  
 } 
 }); 
 

Kotlin

  val 
  
 builder 
  
 = 
  
 AdLoader 
 . 
 Builder 
 ( 
 this 
 , 
  
 "/21775744923/example/native" 
 ) 
  
 . 
 forNativeAd 
  
 { 
  
 nativeAd 
  
 - 
>  
 // Assumes you have a placeholder FrameLayout in your View layout 
  
 // (with ID fl_adplaceholder) where the ad is to be placed. 
  
 val 
  
 frameLayout 
 : 
  
 FrameLayout 
  
 = 
  
 findViewById 
 ( 
 R 
 . 
 id 
 . 
 fl_adplaceholder 
 ) 
  
 // Assumes that your ad layout is in a file call native_ad_layout.xml 
  
 // in the res/layout folder 
  
 val 
  
 adView 
  
 = 
  
 layoutInflater 
  
 . 
 inflate 
 ( 
 R 
 . 
 layout 
 . 
 native_ad_layout 
 , 
  
 null 
 ) 
  
 as 
  
 NativeAdView 
  
 // This method sets the assets into the ad view. 
  
 displayNativeAd 
 ( 
 nativeAd 
 , 
  
 adView 
 ) 
  
 frameLayout 
 . 
 removeAllViews 
 () 
  
 frameLayout 
 . 
 addView 
 ( 
 adView 
 ) 
  
 } 
 

Jetpack Compose

  @Composable 
 /** Load and display a native ad. */ 
 fun 
  
 NativeScreen 
 () 
  
 { 
  
 var 
  
 nativeAd 
  
 by 
  
 remember 
  
 { 
  
 mutableStateOf<NativeAd?>( 
 null 
 ) 
  
 } 
  
 val 
  
 context 
  
 = 
  
 LocalContext 
 . 
 current 
  
 var 
  
 isDisposed 
  
 by 
  
 remember 
  
 { 
  
 mutableStateOf 
 ( 
 false 
 ) 
  
 } 
  
 DisposableEffect 
 ( 
 Unit 
 ) 
  
 { 
  
 // Load the native ad when we launch this screen 
  
 loadNativeAd 
 ( 
  
 context 
  
 = 
  
 context 
 , 
  
 onAdLoaded 
  
 = 
  
 { 
  
 ad 
  
 - 
>  
 // Handle the native ad being loaded. 
  
 if 
  
 ( 
 ! 
 isDisposed 
 ) 
  
 { 
  
 nativeAd 
  
 = 
  
 ad 
  
 } 
  
 else 
  
 { 
  
 // Destroy the native ad if loaded after the screen is disposed. 
  
 ad 
 . 
 destroy 
 () 
  
 } 
  
 }, 
  
 ) 
  
 // Destroy the native ad to prevent memory leaks when we dispose of this screen. 
  
 onDispose 
  
 { 
  
 isDisposed 
  
 = 
  
 true 
  
 nativeAd 
 ?. 
 destroy 
 () 
  
 nativeAd 
  
 = 
  
 null 
  
 } 
  
 } 
  
 // Display the native ad view with a user defined template. 
  
 nativeAd 
 ?. 
 let 
  
 { 
  
 adValue 
  
 - 
>  
 DisplayNativeAdView 
 ( 
 adValue 
 ) 
  
 } 
 } 
 fun 
  
 loadNativeAd 
 ( 
 context 
 : 
  
 Context 
 , 
  
 onAdLoaded 
 : 
  
 ( 
 NativeAd 
 ) 
  
 - 
>  
 Unit 
 ) 
  
 { 
  
 val 
  
 adLoader 
  
 = 
  
 AdLoader 
 . 
 Builder 
 ( 
 context 
 , 
  
 NATIVE_AD_UNIT_ID 
 ) 
  
 . 
 forNativeAd 
  
 { 
  
 nativeAd 
  
 - 
>  
 onAdLoaded 
 ( 
 nativeAd 
 ) 
  
 } 
  
 . 
 withAdListener 
 ( 
  
 object 
  
 : 
  
 AdListener 
 () 
  
 { 
  
 override 
  
 fun 
  
 onAdFailedToLoad 
 ( 
 error 
 : 
  
 LoadAdError 
 ) 
  
 { 
  
 Log 
 . 
 e 
 ( 
 TAG 
 , 
  
 "Native ad failed to load: 
 ${ 
 error 
 . 
 message 
 } 
 " 
 ) 
  
 } 
  
 override 
  
 fun 
  
 onAdLoaded 
 () 
  
 { 
  
 Log 
 . 
 d 
 ( 
 TAG 
 , 
  
 "Native ad was loaded." 
 ) 
  
 } 
  
 override 
  
 fun 
  
 onAdImpression 
 () 
  
 { 
  
 Log 
 . 
 d 
 ( 
 TAG 
 , 
  
 "Native ad recorded an impression." 
 ) 
  
 } 
  
 override 
  
 fun 
  
 onAdClicked 
 () 
  
 { 
  
 Log 
 . 
 d 
 ( 
 TAG 
 , 
  
 "Native ad was clicked." 
 ) 
  
 } 
  
 } 
  
 ) 
  
 . 
 build 
 () 
  
 adLoader 
 . 
 loadAd 
 ( 
 AdRequest 
 . 
 Builder 
 (). 
 build 
 ()) 
 } 
  
 

Note that all assets for a given native ad should be rendered inside the NativeAdView layout. Google Mobile Ads SDK attempts to log a warning when native assets are rendered outside of a native ad view layout.

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

Display the native ad

The following example demonstrates how to display a native ad:

Java

  private 
  
 void 
  
 displayNativeAd 
 ( 
 ViewGroup 
  
 parent 
 , 
  
 NativeAd 
  
 ad 
 ) 
  
 { 
  
 // Inflate a layout and add it to the parent ViewGroup. 
  
 LayoutInflater 
  
 inflater 
  
 = 
  
 ( 
 LayoutInflater 
 ) 
  
 parent 
 . 
 getContext 
 () 
  
 . 
 getSystemService 
 ( 
 Context 
 . 
 LAYOUT_INFLATER_SERVICE 
 ); 
  
 NativeAdView 
  
 adView 
  
 = 
  
 ( 
 NativeAdView 
 ) 
  
 inflater 
  
 . 
 inflate 
 ( 
 R 
 . 
 layout 
 . 
  ad_layout_file 
 
 , 
  
 parent 
 ); 
  
 // Locate the view that will hold the headline, set its text, and call the 
  
 // NativeAdView's setHeadlineView method to register it. 
  
 TextView 
  
 headlineView 
  
 = 
  
 adView 
 . 
 findViewById<TextView> 
 ( 
 R 
 . 
 id 
 . 
 ad_headline 
 ); 
  
 headlineView 
 . 
 setText 
 ( 
 ad 
 . 
 getHeadline 
 ()); 
  
 adView 
 . 
 setHeadlineView 
 ( 
 headlineView 
 ); 
  
 // Repeat the process for the other assets in the NativeAd 
  
 // using additional view objects (Buttons, ImageViews, etc). 
  
 // If you use a MediaView, call theNativeAdView.setMediaView() method 
  
 // before calling the NativeAdView.setNativeAd() method. 
  
 MediaView 
  
 mediaView 
  
 = 
  
 ( 
 MediaView 
 ) 
  
 adView 
 . 
 findViewById 
 ( 
 R 
 . 
 id 
 . 
 ad_media 
 ); 
  
 adView 
 . 
 setMediaView 
 ( 
 mediaView 
 ); 
  
 // Register the native ad with its ad view. 
  
 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 
  
 displayNativeAd 
 ( 
 parent 
 : 
  
 ViewGroup 
 , 
  
 ad 
 : 
  
 NativeAd 
 ) 
  
 { 
  
 // 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 
 . 
  ad_layout_file 
 
 , 
  
 parent 
 ) 
  
 as 
  
 NativeAdView 
  
 // Locate the view that will hold the headline, set its text, and use the 
  
 // NativeAdView's headlineView property to register it. 
  
 val 
  
 headlineView 
  
 = 
  
 adView 
 . 
 findViewById<TextView> 
 ( 
 R 
 . 
 id 
 . 
 ad_headline 
 ) 
  
 headlineView 
 . 
 text 
  
 = 
  
 ad 
 . 
 headline 
  
 adView 
 . 
 headlineView 
  
 = 
  
 headlineView 
  
 // Repeat the process for the other assets in the NativeAd using 
  
 // additional view objects (Buttons, ImageViews, etc). 
  
 val 
  
 mediaView 
  
 = 
  
 adView 
 . 
 findViewById<MediaView> 
 ( 
 R 
 . 
 id 
 . 
 ad_media 
 ) 
  
 adView 
 . 
 mediaView 
  
 = 
  
 mediaView 
  
 // Call the NativeAdView'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 
 ) 
 } 
 

Jetpack Compose

  @Composable 
 /** Display a native ad with a user defined template. */ 
 fun 
  
 DisplayNativeAdView 
 ( 
 nativeAd 
 : 
  
 NativeAd 
 ) 
  
 { 
  
 val 
  
 context 
  
 = 
  
 LocalContext 
 . 
 current 
  
 Box 
 ( 
 modifier 
  
 = 
  
 Modifier 
 . 
 padding 
 ( 
 8. 
 dp 
 ). 
 wrapContentHeight 
 ( 
 Alignment 
 . 
 Top 
 )) 
  
 { 
  
 // Call the NativeAdView composable to display the native ad. 
  
 NativeAdView 
  
 { 
  
 // Inside the NativeAdView composable, display the native ad assets. 
  
 Column 
 ( 
 Modifier 
 . 
 align 
 ( 
 Alignment 
 . 
 TopStart 
 ). 
 wrapContentHeight 
 ( 
 Alignment 
 . 
 Top 
 )) 
  
 { 
  
 // Display the ad attribution. 
  
 NativeAdAttribution 
 ( 
 text 
  
 = 
  
 context 
 . 
 getString 
 ( 
 R 
 . 
 string 
 . 
 attribution 
 )) 
  
 Row 
  
 { 
  
 // If available, display the icon asset. 
  
 nativeAd 
 . 
 icon 
 ?. 
 let 
  
 { 
  
 icon 
  
 - 
>  
 NativeAdIconView 
 ( 
 Modifier 
 . 
 padding 
 ( 
 5. 
 dp 
 )) 
  
 { 
  
 icon 
 . 
 drawable 
 ?. 
 toBitmap 
 () 
 ?. 
 let 
  
 { 
  
 bitmap 
  
 - 
>  
 Image 
 ( 
 bitmap 
  
 = 
  
 bitmap 
 . 
 asImageBitmap 
 (), 
  
 "Icon" 
 ) 
  
 } 
  
 } 
  
 } 
  
 Column 
  
 { 
  
 // If available, display the headline asset. 
  
 nativeAd 
 . 
 headline 
 ?. 
 let 
  
 { 
  
 NativeAdHeadlineView 
  
 { 
  
 Text 
 ( 
 text 
  
 = 
  
 it 
 , 
  
 style 
  
 = 
  
 MaterialTheme 
 . 
 typography 
 . 
 headlineLarge 
 ) 
  
 } 
  
 } 
  
 // If available, display the star rating asset. 
  
 nativeAd 
 . 
 starRating 
 ?. 
 let 
  
 { 
  
 NativeAdStarRatingView 
  
 { 
  
 Text 
 ( 
 text 
  
 = 
  
 "Rated 
 $ 
 it 
 " 
 , 
  
 style 
  
 = 
  
 MaterialTheme 
 . 
 typography 
 . 
 labelMedium 
 ) 
  
 } 
  
 } 
  
 } 
  
 } 
  
 // If available, display the body asset. 
  
 nativeAd 
 . 
 body 
 ?. 
 let 
  
 { 
  
 NativeAdBodyView 
  
 { 
  
 Text 
 ( 
 text 
  
 = 
  
 it 
 ) 
  
 } 
  
 } 
  
 // Display the media asset. 
  
 NativeAdMediaView 
 ( 
 Modifier 
 . 
 fillMaxWidth 
 (). 
 height 
 ( 
 500. 
 dp 
 ). 
 fillMaxHeight 
 ()) 
  
 Row 
 ( 
 Modifier 
 . 
 align 
 ( 
 Alignment 
 . 
 End 
 ). 
 padding 
 ( 
 5. 
 dp 
 )) 
  
 { 
  
 // If available, display the price asset. 
  
 nativeAd 
 . 
 price 
 ?. 
 let 
  
 { 
  
 NativeAdPriceView 
 ( 
 Modifier 
 . 
 padding 
 ( 
 5. 
 dp 
 ). 
 align 
 ( 
 Alignment 
 . 
 CenterVertically 
 )) 
  
 { 
  
 Text 
 ( 
 text 
  
 = 
  
 it 
 ) 
  
 } 
  
 } 
  
 // If available, display the store asset. 
  
 nativeAd 
 . 
 store 
 ?. 
 let 
  
 { 
  
 NativeAdStoreView 
 ( 
 Modifier 
 . 
 padding 
 ( 
 5. 
 dp 
 ). 
 align 
 ( 
 Alignment 
 . 
 CenterVertically 
 )) 
  
 { 
  
 Text 
 ( 
 text 
  
 = 
  
 it 
 ) 
  
 } 
  
 } 
  
 // If available, display the call to action asset. 
  
 // Note: The Jetpack Compose button implements a click handler which overrides the native 
  
 // ad click handler, causing issues. Use the NativeAdButton which does not implement a 
  
 // click handler. To handle native ad clicks, use the NativeAd AdListener onAdClicked 
  
 // callback. 
  
 nativeAd 
 . 
 callToAction 
 ?. 
 let 
  
 { 
  
 callToAction 
  
 - 
>  
 NativeAdCallToActionView 
 ( 
 Modifier 
 . 
 padding 
 ( 
 5. 
 dp 
 )) 
  
 { 
  
 NativeAdButton 
 ( 
 text 
  
 = 
  
 callToAction 
 ) 
  
 } 
  
 } 
  
 } 
  
 } 
  
 } 
  
 } 
 } 
  
 

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, 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 is 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 .

Handle clicks

Don't implement any custom click handlers on any views over or within the native ad view. Clicks on the ad view assets are handled by the SDK as long as you correctly populate and register the asset views.

To listen for clicks, implement the Google Mobile Ads SDK click callback:

Java

  AdLoader 
  
 adLoader 
  
 = 
  
 new 
  
 AdLoader 
 . 
 Builder 
 ( 
 context 
 , 
  
 "/21775744923/example/native" 
 ) 
  
 // ... 
  
 . 
 withAdListener 
 ( 
 new 
  
 AdListener 
 () 
  
 { 
  
 @Override 
  
 public 
  
 void 
  
 onAdFailedToLoad 
 ( 
 LoadAdError 
  
 adError 
 ) 
  
 { 
  
 // Handle the failure by logging. 
  
 } 
  
 @Override 
  
 public 
  
 void 
  
 onAdClicked 
 () 
  
 { 
  
 // Log the click event or other custom behavior. 
  
 } 
  
 }) 
  
 . 
 build 
 (); 
 

Kotlin

  val 
  
 adLoader 
  
 = 
  
 AdLoader 
 . 
 Builder 
 ( 
 this 
 , 
  
 "/21775744923/example/native" 
 ) 
  
 // ... 
  
 . 
 withAdListener 
 ( 
 object 
  
 : 
  
 AdListener 
 () 
  
 { 
  
 override 
  
 fun 
  
 onAdFailedToLoad 
 ( 
 adError 
 : 
  
 LoadAdError 
 ) 
  
 { 
  
 // Handle the failure. 
  
 } 
  
 override 
  
 fun 
  
 onAdClicked 
 () 
  
 { 
  
 // Log the click event or other custom behavior. 
  
 } 
  
 }) 
  
 . 
 build 
 () 
 

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 :

Java

  mediaView 
 . 
 setImageScaleType 
 ( 
 ImageView 
 . 
 ScaleType 
 . 
 CENTER_CROP 
 ); 
 

Kotlin

  mediaView 
 . 
 imageScaleType 
  
 = 
  
 ImageView 
 . 
 ScaleType 
 . 
 CENTER_CROP 
 

MediaContent

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 checking hasVideoContent() .

  • If the ad does not contain a video asset, the mainImage asset is downloaded and placed inside the MediaView instead.

∂## Destroy an ad

After you show a native ad, destroy the ad. The following example destroys a native ad:

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:

 /21775744923/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

Ad Exchange backfill is limited to a select group of publishers. To test the behavior of native backfill ads, use this Ad Manager ad unit:

 /21775744923/example/native-backfill 

It serves sample app install and content ads that include the AdChoices overlay.

Remember to update your code to refer to your actual ad unit and template IDs before going live.

Examples on GitHub

Complete implementation of native ads example:

Java Kotlin JetpackCompose

Next steps

Explore the following topics:

Create a Mobile Website
View Site in Mobile | Classic
Share by: