Zaawansowana reklama natywna

Wybierz platformę: Android iOS

Wyświetlanie reklamy NativeAd

Gdy reklama natywna zostanie wczytana, pakiet SDK do reklam mobilnych Google wywoła detektor dla odpowiedniego formatu reklamy. Aplikacja jest wtedy odpowiedzialna za wyświetlanie reklamy, ale nie musi tego robić od razu. Aby ułatwić wyświetlanie zdefiniowanych przez system formatów reklam, pakiet SDK udostępnia przydatne zasoby, które opisujemy poniżej.

Zdefiniuj klasę NativeAdView

Zdefiniuj klasę NativeAdView. Ta klasa jest klasą ViewGroup i jest kontenerem najwyższego poziomu dla klasy NativeAdView. Każdy widok reklamy natywnej zawiera komponenty reklamy natywnej, takie jak element widoku MediaView lub element widoku Title, który musi być elementem podrzędnym obiektu NativeAdView.

Układ XML

Dodaj do projektu plik XML NativeAdView:

<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

Dodaj moduł JetpackComposeDemo/compose-util, który zawiera pomocnicze funkcje do tworzenia komponentu NativeAdView i jego zasobów.

Za pomocą modułu compose-util utwórz 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.
        }
    }

Obsługa załadowanej reklamy natywnej

Gdy reklama natywna zostanie wczytana, obsłuż zdarzenie wywołania zwrotnego, rozwiń widok reklamy natywnej i dodaj go do hierarchii widoków:

Java

AdLoader.Builder builder = new AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110")
    .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.
            populateNativeAdView(nativeAd, adView);
            frameLayout.removeAllViews();
            frameLayout.addView(adView);
        }
});

Kotlin

val builder = AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110")
    .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.
        populateNativeAdView(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())
}

Pamiętaj, że wszystkie komponenty danej reklamy natywnej powinny być renderowane w NativeAdView. Pakiet SDK do reklam mobilnych Google próbuje rejestrować ostrzeżenie, gdy zasoby natywne są renderowane poza układem widoku reklamy natywnej.

Klasy widoku reklamy udostępniają też metody rejestrowania widoku używanego w przypadku każdego komponentu oraz metodę rejestrowania samego obiektu NativeAd. Rejestrowanie wyświetleń w ten sposób umożliwia pakietowi SDK automatyczne wykonywanie takich zadań jak:

  • Rejestrowanie kliknięć
  • Rejestrowanie wyświetleń, gdy pierwszy piksel jest widoczny na ekranie
  • Wyświetlanie nakładki Informacja

Nakładka Informacja

Pakiet SDK dodaje nakładkę Informacja do każdego widoku reklamy. Zostaw miejsce w wybranym rogu widoku reklamy natywnej na automatycznie wstawiane logo „Informacja”. Ważne jest też, aby nakładka Informacja była dobrze widoczna, dlatego należy odpowiednio dobrać kolory tła i obrazy. Więcej informacji o wyglądzie i funkcjach nakładki znajdziesz w opisach pól reklam natywnych.

Oznaczenie reklamy

Musisz wyświetlać oznaczenie reklamy, aby wskazać, że wyświetlenie jest reklamą. Więcej informacji znajdziesz w naszych wytycznych dotyczących zasad.

Przykładowy kod

Aby wyświetlić reklamę natywną, wykonaj te czynności:

  1. Utwórz instancję klasy NativeAdView.
  2. Aby wyświetlić każdy komponent reklamy:

    1. Wypełnij widok komponentu komponentem z obiektu reklamy.
    2. Zarejestruj widok komponentu za pomocą klasy NativeAdView.
  3. Zarejestruj MediaView jeśli układ reklamy natywnej zawiera duży zasób multimedialny.

  4. Zarejestruj obiekt reklamy w klasie NativeAdView.

Oto przykładowa funkcja, która wyświetla wartość NativeAd:

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 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 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);
}

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) }
          }
        }
      }
    }
  }
}

Oto poszczególne zadania:

  1. Rozszerzanie układu

    Java

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

    Kotlin

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

    Ten kod rozszerza układ XML, który zawiera widoki do wyświetlania reklamy natywnej, a następnie lokalizuje odwołanie do elementu NativeAdView. Pamiętaj, że możesz też ponownie użyć istniejącego NativeAdView, jeśli znajduje się on we fragmencie lub aktywności, albo dynamicznie utworzyć instancję bez użycia pliku układu.

  2. Wypełnianie i rejestrowanie wyświetleń komponentów

    Ten przykładowy kod lokalizuje widok używany do wyświetlania nagłówka, ustawia jego tekst za pomocą komponentu tekstowego dostarczonego przez obiekt reklamy i rejestruje go w obiekcie NativeAdView:

    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
    

    Ten proces lokalizowania widoku, ustawiania jego wartości i rejestrowania go w klasie widoku reklamy powinien być powtarzany w przypadku każdego komponentu dostarczonego przez obiekt reklamy natywnej, który będzie wyświetlany w aplikacji.

  3. Obsługa kliknięć

    Nie implementuj żadnych niestandardowych funkcji obsługi kliknięć w żadnych widokach nad widokiem reklamy natywnej ani w nim. Kliknięcia komponentów widoku reklamy są obsługiwane przez pakiet SDK, o ile prawidłowo wypełnisz i zarejestrujesz widoki komponentów, jak opisano w poprzedniej sekcji.

    Aby wykrywać kliknięcia, zaimplementuj wywołanie zwrotne kliknięcia pakietu SDK do reklam mobilnych Google:

    Java

    AdLoader adLoader = new AdLoader.Builder(context, "ca-app-pub-3940256099942544/2247696110")
        // ...
        .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, "ca-app-pub-3940256099942544/2247696110")
        // ...
        .withAdListener(object : AdListener() {
            override fun onAdFailedToLoad(adError: LoadAdError) {
                // Handle the failure.
            }
            override fun onAdClicked() {
                // Log the click event or other custom behavior.
            }
        })
        .build()
    
  4. Zarejestruj MediaView

    Jeśli w układzie reklamy natywnej chcesz uwzględnić główny zasób obrazu, zamiast zasobu ImageView musisz użyć zasobu MediaView.

    MediaView to specjalny View przeznaczony do wyświetlania głównego komponentu multimedialnego, czyli filmu lub obrazu.

    MediaView można zdefiniować w układzie XML lub utworzyć dynamicznie. Powinien on być umieszczony w hierarchii widoków elementu NativeAdView, tak jak każdy inny widok komponentu. Aplikacje korzystające z MediaView muszą zarejestrować go w NativeAdView:

    Java

     // Populate and register the media asset view.
     nativeAdView.setMediaView(nativeAdBinding.adMedia);
    

    Kotlin

     // Populate and register the media asset view.
     nativeAdView.mediaView = nativeAdBinding.adMedia
    

    ImageScaleType

    Klasa MediaView ma właściwość ImageScaleType podczas wyświetlania obrazów. Jeśli chcesz zmienić sposób skalowania obrazu w MediaView, ustaw odpowiedni parametr ImageView.ScaleType za pomocą metody setImageScaleType()MediaView:

    Java

    mediaView.setImageScaleType(ImageView.ScaleType.CENTER_CROP);
    

    Kotlin

    mediaView.imageScaleType = ImageView.ScaleType.CENTER_CROP
    

    MediaContent

    Klasa MediaContent zawiera dane związane z treściami multimedialnymi reklamy natywnej, które są wyświetlane za pomocą klasy MediaView. Gdy właściwość MediaView mediaContent jest ustawiona na instancję MediaContent:

    • Jeśli zasób wideo jest dostępny, jest buforowany i odtwarzany w MediaView. Dostępność zasobu wideo możesz sprawdzić, klikając hasVideoContent().

    • Jeśli reklama nie zawiera komponentu wideo, komponent mainImage jest pobierany i umieszczany w miejscu MediaView.

    Domyślnie mainImage to pierwszy pobrany komponent z obrazem. Jeśli używasz setReturnUrlsForImageAssets(true), mainImage ma wartość null i musisz ustawić właściwość mainImage na ręcznie pobrany obraz. Pamiętaj, że ten obraz będzie używany tylko wtedy, gdy nie będzie dostępny żaden komponent wideo.

  5. Zarejestruj obiekt reklamy natywnej

    Ten ostatni krok rejestruje obiekt reklamy natywnej w widoku odpowiedzialnym za jej wyświetlanie.

    Java

    adView.setNativeAd(ad);
    

    Kotlin

    adView.setNativeAd(ad)
    

Usuwanie reklamy

Po wyświetleniu reklamy natywnej usuń ją. Ten przykład niszczy reklamę natywną:

Java

nativeAd.destroy();

Kotlin

nativeAd.destroy()

Przykłady w GitHubie

Przykład pełnej implementacji reklam natywnych:

Java Kotlin JetpackCompose

Dalsze kroki

Zapoznaj się z tymi tematami: