<br />

<br />

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

> [!IMPORTANT]
> **Key Point:** Review the [Native ads policies and
> guidelines](https://support.google.com/admanager/answer/7031536) for guidance on how to render your native ads.

### Define the `NativeAdView` class

Define a [`NativeAdView`](https://developers.google.com/ad-manager/mobile-ads-sdk/android/next-gen/reference/com/google/android/libraries/ads/mobile/sdk/nativead/NativeAdView.md.txt) class. This class is a
[`ViewGroup`](https://developer.android.com/reference/android/view/ViewGroup.html)
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:

```xml
<com.google.android.libraries.ads.mobile.sdk.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.libraries.ads.mobile.sdk.nativead.NativeAdView>
```

### Jetpack Compose

1. Include the [JetpackCompose Utilities](https://github.com/googleads/googleads-mobile-android-examples/tree/main/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/formats/compose_utils/) folder. This folder includes helpers for composing the `NativeAdView` object and assets.

Compose a `NativeAdView`:

```kotlin
  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:

### Kotlin

```kotlin
// Build an ad request with native ad options to customize the ad.
val adTypes = listOf(NativeAd.NativeAdType.NATIVE)
val adRequest = NativeAdRequest
  .Builder("/21775744923/example/native", adTypes)
  .build()

val adCallback =
  object : NativeAdLoaderCallback {
    override fun onNativeAdLoaded(nativeAd: NativeAd) {
      activity?.runOnUiThread {

        val nativeAdBinding = NativeAdBinding.inflate(layoutInflater)
        val adView = nativeAdBinding.root
        val frameLayout = myActivityLayout.nativeAdPlaceholder

        // Populate and register the native ad asset views.
        displayNativeAd(nativeAd, nativeAdBinding)

        // Remove all old ad views and add the new native ad
        // view to the view hierarchy.
        frameLayout.removeAllViews()
        frameLayout.addView(adView)
      }
    }
  }

// Load the native ad with our request and callback.
NativeAdLoader.load(adRequest, adCallback)
```

### Java

```java
// Build an ad request with native ad options to customize the ad.
List<NativeAd.NativeAdType> adTypes = Arrays.asList(NativeAd.NativeAdType.NATIVE);
NativeAdRequest adRequest = new NativeAdRequest
                                .Builder("/21775744923/example/native", adTypes)
                                .build();

NativeAdLoaderCallback adCallback = new NativeAdLoaderCallback() {
    @Override
    public void onNativeAdLoaded(NativeAd nativeAd) {
      if (getActivity() != null) {
        getActivity()
          .runOnUiThread(() -> {
            // Inflate the native ad view and add it to the view hierarchy.
            NativeAdBinding nativeAdBinding = NativeAdBinding.inflate(getLayoutInflater());
            NativeAdView adView = (NativeAdView) nativeAdBinding.getRoot();
            FrameLayout frameLayout = myActivityLayout.nativeAdPlaceholder;

            // Populate and register the native ad asset views.
            displayNativeAd(nativeAd, nativeAdBinding);

            // Remove all old ad views and add the new native ad
            // view to the view hierarchy.
            frameLayout.removeAllViews();
            frameLayout.addView(adView);
        });
      }
    }
};

// Load the native ad with our request and callback.
NativeAdLoader.load(adRequest, adCallback);
```

Note that all assets for a given native ad should be rendered inside the
`NativeAdView` layout. GMA Next-Gen 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:

### Kotlin

```kotlin
private fun displayNativeAd(nativeAd: NativeAd, nativeAdBinding : NativeAdBinding) {
  // Set the native ad view elements.
  val nativeAdView = nativeAdBinding.root
  nativeAdView.advertiserView = nativeAdBinding.adAdvertiser
  nativeAdView.bodyView = nativeAdBinding.adBody
  nativeAdView.callToActionView = nativeAdBinding.adCallToAction
  nativeAdView.headlineView = nativeAdBinding.adHeadline
  nativeAdView.iconView = nativeAdBinding.adAppIcon
  nativeAdView.priceView = nativeAdBinding.adPrice
  nativeAdView.starRatingView = nativeAdBinding.adStars
  nativeAdView.storeView = nativeAdBinding.adStore

  // Set the view element with the native ad assets.
  nativeAdBinding.adAdvertiser.text = nativeAd.advertiser
  nativeAdBinding.adBody.text = nativeAd.body
  nativeAdBinding.adCallToAction.text = nativeAd.callToAction
  nativeAdBinding.adHeadline.text = nativeAd.headline
  nativeAdBinding.adAppIcon.setImageDrawable(nativeAd.icon?.drawable)
  nativeAdBinding.adPrice.text = nativeAd.price
  nativeAd.starRating?.toFloat().let { value ->
    nativeAdBinding.adStars.rating = value
  }
  nativeAdBinding.adStore.text = nativeAd.store

  // Hide views for assets that don't have data.
  nativeAdBinding.adAdvertiser.visibility = getAssetViewVisibility(nativeAd.advertiser)
  nativeAdBinding.adBody.visibility = getAssetViewVisibility(nativeAd.body)
  nativeAdBinding.adCallToAction.visibility = getAssetViewVisibility(nativeAd.callToAction)
  nativeAdBinding.adHeadline.visibility = getAssetViewVisibility(nativeAd.headline)
  nativeAdBinding.adAppIcon.visibility = getAssetViewVisibility(nativeAd.icon)
  nativeAdBinding.adPrice.visibility = getAssetViewVisibility(nativeAd.price)
  nativeAdBinding.adStars.visibility = getAssetViewVisibility(nativeAd.starRating)
  nativeAdBinding.adStore.visibility = getAssetViewVisibility(nativeAd.store)

  // Inform GMA Next-Gen SDK that you have finished populating
  // the native ad views with this native ad.
  nativeAdView.registerNativeAd(nativeAd, nativeAdBinding.adMedia)
}

/**
* Determines the visibility of an asset view based on the presence of its asset.
*
* @param asset The native ad asset to check for nullability.
* @return [View.VISIBLE] if the asset is not null, [View.INVISIBLE] otherwise.
*/
private fun getAssetViewVisibility(asset: Any?): Int {
  return if (asset == null) View.INVISIBLE else View.VISIBLE
}
```

### Java

```java
private void displayNativeAd(ad: NativeAd, nativeAdBinding : NativeAdBinding) {
  // Set the native ad view elements.
  NativeAdView nativeAdView = nativeAdBinding.getRoot();
  nativeAdView.setAdvertiserView(nativeAdBinding.adAdvertiser);
  nativeAdView.setBodyView(nativeAdBinding.adBody);
  nativeAdView.setCallToActionView(nativeAdBinding.adCallToAction);
  nativeAdView.setHeadlineView(nativeAdBinding.adHeadline);
  nativeAdView.setIconView(nativeAdBinding.adAppIcon);
  nativeAdView.setPriceView(nativeAdBinding.adPrice);
  nativeAdView.setStarRatingView(nativeAdBinding.adStars);
  nativeAdView.setStoreView(nativeAdBinding.adStore);

  // Set the view element with the native ad assets.
  nativeAdBinding.adAdvertiser.setText(nativeAd.getAdvertiser());
  nativeAdBinding.adBody.setText(nativeAd.getBody());
  nativeAdBinding.adCallToAction.setText(nativeAd.getCallToAction());
  nativeAdBinding.adHeadline.setText(nativeAd.getHeadline());
  if (nativeAd.getIcon() != null) {
      nativeAdBinding.adAppIcon.setImageDrawable(nativeAd.getIcon().getDrawable());
  }
  nativeAdBinding.adPrice.setText(nativeAd.getPrice());
  if (nativeAd.getStarRating() != null) {
      nativeAdBinding.adStars.setRating(nativeAd.getStarRating().floatValue());
  }
  nativeAdBinding.adStore.setText(nativeAd.getStore());

  // Hide views for assets that don't have data.
  nativeAdBinding.adAdvertiser.setVisibility(getAssetViewVisibility(nativeAd.getAdvertiser()));
  nativeAdBinding.adBody.setVisibility(getAssetViewVisibility(nativeAd.getBody()));
  nativeAdBinding.adCallToAction.setVisibility(getAssetViewVisibility(nativeAd.getCallToAction()));
  nativeAdBinding.adHeadline.setVisibility(getAssetViewVisibility(nativeAd.getHeadline()));
  nativeAdBinding.adAppIcon.setVisibility(getAssetViewVisibility(nativeAd.getIcon()));
  nativeAdBinding.adPrice.setVisibility(getAssetViewVisibility(nativeAd.getPrice()));
  nativeAdBinding.adStars.setVisibility(getAssetViewVisibility(nativeAd.getStarRating()));
  nativeAdBinding.adStore.setVisibility(getAssetViewVisibility(nativeAd.getStore()));

  // Inform GMA Next-Gen SDK that you have finished populating
  // the native ad views with this native ad.
  nativeAdView.registerNativeAd(nativeAd, nativeAdBinding.adMedia);
}

/**
* Determines the visibility of an asset view based on the presence of its asset.
*
* @param asset The native ad asset to check for nullability.
* @return {@link View#VISIBLE} if the asset is not null, {@link View#INVISIBLE} otherwise.
*/
private int getAssetViewVisibility(Object asset) {
    return (asset == null) ? View.INVISIBLE : View.VISIBLE;
}
```

> [!NOTE]
> **Note:** If you prefer to render your native ad without a `MediaView` instance, pass the `null` value for the media view parameter when calling the `registerNativeAd()` method.

### 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](https://developers.google.com/ad-manager/mobile-ads-sdk/android/native/options#setadchoicesplacement)
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](https://support.google.com/admanager/answer/7031536#adchoices).

> [!NOTE]
> **Note:** AdChoices are displayed for direct-sold ads only in the EEA.

### 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](https://support.google.com/admanager/answer/7031536#ad-attribution).

### 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 GMA Next-Gen SDK click callback:

### Kotlin

```kotlin
private fun setEventCallback(nativeAd: NativeAd) {
  nativeAd.adEventCallback =
    object : NativeAdEventCallback {
      override fun onAdClicked() {
        Log.d(Constant.TAG, "Native ad recorded a click.")
      }
    }
}
```

### Java

```java
private void setEventCallback(NativeAd nativeAd) {
  nativeAd.setAdEventCallback(new NativeAdEventCallback() {
      @Override
      public void onAdClicked() {
        Log.d(Constant.TAG, "Native ad recorded a click.");
      }
  });
}
```

#### 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`:

### Kotlin

```kotlin
nativeAdViewBinding.mediaView.imageScaleType = ImageView.ScaleType.CENTER_CROP
```

### Java

```java
nativeAdViewBinding.mediaView.setImageScaleType(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.

### Add creative summary


> [!WARNING]
> Warning: Access to this feature is limited. To request access, reach out to your account manager.

<br />

In conversational and AI chat applications, GMA Next-Gen SDK provides a creative
summary asset (`creativeSummary`) for the ad creative. You can integrate
ads into your app's chat flows with an introductory message.

#### Add the text view to your layout

Add a `TextView` for the creative summary asset inside your `NativeAdView`
container layout:

```xml
<TextView
    android:id="@+id/ad_creative_summary"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="13sp" />
```

#### Populate and register the view

Populate the `TextView` with `creativeSummary` and register it with the
`creativeSummaryView` property on your `NativeAdView` object. Registering the
view enables automatic click tracking for the creative summary asset.

> [!NOTE]
> **Note:** The `creativeSummary` and `creativeSummaryView` APIs require the `@OptIn(ExperimentalApi::class)` annotation.

### Kotlin

```kotlin
private fun populateCreativeSummary(
  nativeAd: NativeAd,
  nativeAdBinding: NativeAdBinding,
  nativeAdView: NativeAdView,
) {
  val summary = nativeAd.creativeSummary
  if (summary == null) {
    nativeAdBinding.adCreativeSummary.visibility = View.GONE
    return
  }

  nativeAdBinding.adCreativeSummary.text = summary
  nativeAdBinding.adCreativeSummary.visibility = View.VISIBLE
  nativeAdView.creativeSummaryView = nativeAdBinding.adCreativeSummary
}
```

### Java

```java
private void populateCreativeSummary(
    NativeAd nativeAd, NativeAdBinding nativeAdBinding, NativeAdView nativeAdView) {
  String summary = nativeAd.getCreativeSummary();
  if (summary == null) {
    nativeAdBinding.adCreativeSummary.setVisibility(View.GONE);
    return;
  }

  nativeAdBinding.adCreativeSummary.setText(summary);
  nativeAdBinding.adCreativeSummary.setVisibility(View.VISIBLE);
  nativeAdView.setCreativeSummaryView(nativeAdBinding.adCreativeSummary);
}
```

#### Click tracking and modified text

- **Direct rendering:** When you render the exact `creativeSummary` string provided by the SDK, register it to the `creativeSummaryView` property inside the `NativeAdView` container to enable SDK click handling.
- **Modified introductions:** If your app modifies, summarizes, or appends custom conversational text to the creative summary, place the modified text outside the `NativeAdView` container.

## Destroy an ad

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

### Kotlin

```kotlin
nativeAd.destroy()
```

### Java

```java
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.

## Next steps

Explore the following topics:

- [User privacy](https://developers.google.com/ad-manager/mobile-ads-sdk/android/next-gen/privacy.md.txt)

## Example

Download and run the
[example app](https://github.com/googleads/gma-next-gen-sdk-android-examples)
that demonstrates the use of the GMA Next-Gen SDK.