Configurações nativas no Android e iOS

Os anúncios nativos são apresentados aos usuários que usam componentes de IU nativos da plataforma, por exemplo, um View no Android ou um UIView no iOS.

Neste guia, mostramos como carregar, mostrar e personalizar anúncios nativos usando código específico da plataforma.

Pré-requisitos

Sempre teste com anúncios de teste

Ao criar e testar seus apps, use anúncios de teste em vez de publicidade de produção ativa. A maneira mais fácil de carregar anúncios de teste é usar nosso ID de bloco de anúncios de teste dedicado a anúncios nativos:

Android

ca-app-pub-3940256099942544/2247696110

iOS

ca-app-pub-3940256099942544/3986624511

Os blocos de anúncios de teste são configurados para retornar anúncios de teste para cada solicitação. Portanto, você pode usá-los nos seus próprios apps durante a programação, o teste e a depuração. Basta substituí-los pelos seus próprios IDs de bloco de anúncios antes de publicar o app.

Configurações específicas da plataforma

Para criar anúncios nativos, você precisa escrever um código específico para iOS e Android, seguido pela modificação da implementação do Dart para aproveitar as mudanças feitas no código nativo.

Android

Importar o plug-in

A implementação do plug-in de anúncios para dispositivos móveis do Google no Android exige uma classe que implemente a API NativeAdFactory. Para fazer referência a essa API no seu projeto Android, adicione as seguintes linhas ao settings.gradle:

def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
    pluginsFile.withInputStream { stream -> plugins.load(stream) }
}

plugins.each { name, path ->
    def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
    include ":$name"
    project(":$name").projectDir = pluginDirectory
}

Implementar a NativeAdFactory

Em seguida, crie uma classe que implemente NativeAdFactory e substitua o método createNativeAd().

package io.flutter.plugins.googlemobileadsexample;

import android.graphics.Color;
import android.view.LayoutInflater;
import android.widget.TextView;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.NativeAdFactory;
import java.util.Map;

/**
 * my_native_ad.xml can be found at
 * github.com/googleads/googleads-mobile-flutter/blob/main/packages/google_mobile_ads/
 *     example/android/app/src/main/res/layout/my_native_ad.xml
 */
class NativeAdFactoryExample implements NativeAdFactory {
  private final LayoutInflater layoutInflater;

  NativeAdFactoryExample(LayoutInflater layoutInflater) {
    this.layoutInflater = layoutInflater;
  }

  @Override
  public NativeAdView createNativeAd(
      NativeAd nativeAd, Map<String, Object> customOptions) {
    final NativeAdView adView =
        (NativeAdView) layoutInflater.inflate(R.layout.my_native_ad, null);

    // Set the media view.
    adView.setMediaView((MediaView) adView.findViewById(R.id.ad_media));

    // Set other ad assets.
    adView.setHeadlineView(adView.findViewById(R.id.ad_headline));
    adView.setBodyView(adView.findViewById(R.id.ad_body));
    adView.setCallToActionView(adView.findViewById(R.id.ad_call_to_action));
    adView.setIconView(adView.findViewById(R.id.ad_app_icon));
    adView.setPriceView(adView.findViewById(R.id.ad_price));
    adView.setStarRatingView(adView.findViewById(R.id.ad_stars));
    adView.setStoreView(adView.findViewById(R.id.ad_store));
    adView.setAdvertiserView(adView.findViewById(R.id.ad_advertiser));

    // The headline and mediaContent are guaranteed to be in every NativeAd.
    ((TextView) adView.getHeadlineView()).setText(nativeAd.getHeadline());
    adView.getMediaView().setMediaContent(nativeAd.getMediaContent());

    // These assets aren't guaranteed to be in every NativeAd, so it's important to
    // check before trying to display them.
    if (nativeAd.getBody() == null) {
      adView.getBodyView().setVisibility(View.INVISIBLE);
    } else {
      adView.getBodyView().setVisibility(View.VISIBLE);
      ((TextView) adView.getBodyView()).setText(nativeAd.getBody());
    }

    if (nativeAd.getCallToAction() == null) {
      adView.getCallToActionView().setVisibility(View.INVISIBLE);
    } else {
      adView.getCallToActionView().setVisibility(View.VISIBLE);
      ((Button) adView.getCallToActionView()).setText(nativeAd.getCallToAction());
    }

    if (nativeAd.getIcon() == null) {
      adView.getIconView().setVisibility(View.GONE);
    } else {
      ((ImageView) adView.getIconView()).setImageDrawable(nativeAd.getIcon().getDrawable());
      adView.getIconView().setVisibility(View.VISIBLE);
    }

    if (nativeAd.getPrice() == null) {
      adView.getPriceView().setVisibility(View.INVISIBLE);
    } else {
      adView.getPriceView().setVisibility(View.VISIBLE);
      ((TextView) adView.getPriceView()).setText(nativeAd.getPrice());
    }

    if (nativeAd.getStore() == null) {
      adView.getStoreView().setVisibility(View.INVISIBLE);
    } else {
      adView.getStoreView().setVisibility(View.VISIBLE);
      ((TextView) adView.getStoreView()).setText(nativeAd.getStore());
    }

    if (nativeAd.getStarRating() == null) {
      adView.getStarRatingView().setVisibility(View.INVISIBLE);
    } else {
      ((RatingBar) adView.getStarRatingView()).setRating(nativeAd.getStarRating()
          .floatValue());
      adView.getStarRatingView().setVisibility(View.VISIBLE);
    }

    if (nativeAd.getAdvertiser() == null) {
      adView.getAdvertiserView().setVisibility(View.INVISIBLE);
    } else {
      adView.getAdvertiserView().setVisibility(View.VISIBLE);
      ((TextView) adView.getAdvertiserView()).setText(nativeAd.getAdvertiser());
    }

    // This method tells the Google Mobile Ads SDK that you have finished populating your
    // native ad view with this native ad.
    adView.setNativeAd(nativeAd);

    return adView;
  }
}

Para conferir um exemplo de configuração do layout NativeAdView, consulte my_native_ad.xml.

Registrar a NativeAdFactory

Cada implementação de NativeAdFactory precisa ser registrada com um factoryId, um identificador String exclusivo, ao chamar MainActivity.configureFlutterEngine(FlutterEngine). O factoryId será usado mais tarde ao instanciar um anúncio nativo no código Dart.

Um NativeAdFactory pode ser implementado e registrado para cada layout de anúncio nativo exclusivo usado pelo app ou um único pode processar todos os layouts.

Ao criar com o add-to-app, o NativeAdFactory também precisa ser desregistrado no cleanUpFlutterEngine(engine).

Depois de criar NativeAdFactoryExample, configure MainActivity da seguinte maneira:

package my.app.path;

import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin;

public class MainActivity extends FlutterActivity {
  @Override
  public void configureFlutterEngine(FlutterEngine flutterEngine) {
    flutterEngine.getPlugins().add(new GoogleMobileAdsPlugin());
    super.configureFlutterEngine(flutterEngine);

    GoogleMobileAdsPlugin.registerNativeAdFactory(flutterEngine,
        "adFactoryExample", NativeAdFactoryExample());
  }

  @Override
  public void cleanUpFlutterEngine(FlutterEngine flutterEngine) {
    GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "adFactoryExample");
  }
}

iOS

Implementar a NativeAdFactory

A implementação do plug-in de anúncios para dispositivos móveis do Google no iOS exige uma classe que implemente a API FLTNativeAdFactory. Crie uma classe que implemente NativeAdFactory e o método createNativeAd().

#import "FLTGoogleMobileAdsPlugin.h"

/**
 * The example NativeAdView.xib can be found at
 * github.com/googleads/googleads-mobile-flutter/blob/main/packages/google_mobile_ads/
 *     example/ios/Runner/NativeAdView.xib
 */
@interface NativeAdFactoryExample : NSObject <FLTNativeAdFactory>
@end

@implementation NativeAdFactoryExample
- (GADNativeAdView *)createNativeAd:(GADNativeAd *)nativeAd
                      customOptions:(NSDictionary *)customOptions {
  // Create and place the ad in the view hierarchy.
  GADNativeAdView *adView =
      [[NSBundle mainBundle] loadNibNamed:@"NativeAdView" owner:nil options:nil].firstObject;

  // Populate the native ad view with the native ad assets.
  // The headline is guaranteed to be present in every native ad.
  ((UILabel *)adView.headlineView).text = nativeAd.headline;

  // These assets are not guaranteed to be present. Check that they are before
  // showing or hiding them.
  ((UILabel *)adView.bodyView).text = nativeAd.body;
  adView.bodyView.hidden = nativeAd.body ? NO : YES;

  [((UIButton *)adView.callToActionView) setTitle:nativeAd.callToAction
                                         forState:UIControlStateNormal];
  adView.callToActionView.hidden = nativeAd.callToAction ? NO : YES;

  ((UIImageView *)adView.iconView).image = nativeAd.icon.image;
  adView.iconView.hidden = nativeAd.icon ? NO : YES;

  ((UILabel *)adView.storeView).text = nativeAd.store;
  adView.storeView.hidden = nativeAd.store ? NO : YES;

  ((UILabel *)adView.priceView).text = nativeAd.price;
  adView.priceView.hidden = nativeAd.price ? NO : YES;

  ((UILabel *)adView.advertiserView).text = nativeAd.advertiser;
  adView.advertiserView.hidden = nativeAd.advertiser ? NO : YES;

  // In order for the SDK to process touch events properly, user interaction
  // should be disabled.
  adView.callToActionView.userInteractionEnabled = NO;

  // Associate the native ad view with the native ad object. This is
  // required to make the ad clickable.
  // Note: this should always be done after populating the ad views.
  adView.nativeAd = nativeAd;

  return adView;
}
@end

Para conferir um exemplo de configuração do layout GADNativeAdView, consulte NativeAdView.xib.

Registrar a NativeAdFactory

Cada FLTNativeAdFactory precisa ser registrado com um factoryId, um identificador String exclusivo, em registerNativeAdFactory:factoryId:nativeAdFactory:. O factoryId será usado mais tarde ao instanciar um anúncio nativo no código Dart.

Um FLTNativeAdFactory pode ser implementado e registrado para cada layout de anúncio nativo exclusivo usado pelo app ou um único pode processar todos os layouts.

Depois de criar FLTNativeAdFactory, configure AppDelegate da seguinte forma:

#import "FLTGoogleMobileAdsPlugin.h"
#import "NativeAdFactoryExample.h"

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
      didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];

  // Must be added after GeneratedPluginRegistrant registerWithRegistry:self];
  // is called.
  NativeAdFactoryExample *nativeAdFactory = [[NativeAdFactoryExample alloc] init];
  [FLTGoogleMobileAdsPlugin registerNativeAdFactory:self
                                          factoryId:@"adFactoryExample"
                                    nativeAdFactory:nativeAdFactory];

  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end

Carregar o anúncio

Depois de adicionar o código específico da plataforma, use o Dart para carregar anúncios. Verifique se factoryID corresponde ao ID que você registrou anteriormente.

class NativeExampleState extends State<NativeExample> {
  NativeAd? _nativeAd;
  bool _nativeAdIsLoaded = false;

 // TODO: replace this test ad unit with your own ad unit.
 final String _adUnitId = Platform.isAndroid
      ? 'ca-app-pub-3940256099942544/2247696110'
      : 'ca-app-pub-3940256099942544/3986624511';

  /// Loads a native ad.
  void loadAd() {
    _nativeAd = NativeAd(
        adUnitId: _adUnitId,
        // Factory ID registered by your native ad factory implementation.
        factoryId: 'adFactoryExample',
        listener: NativeAdListener(
          onAdLoaded: (ad) {
            print('$NativeAd loaded.');
            setState(() {
              _nativeAdIsLoaded = true;
            });
          },
          onAdFailedToLoad: (ad, error) {
            // Dispose the ad here to free resources.
            print('$NativeAd failedToLoad: $error');
            ad.dispose();
          },
        ),
        request: const AdRequest(),
        // Optional: Pass custom options to your native ad factory implementation.
        customOptions: {'custom-option-1', 'custom-value-1'}
    );
    _nativeAd.load();
  }
}

Eventos de anúncios nativos

Para receber notificações sobre eventos relacionados às interações com anúncios nativos, use a propriedade listener do anúncio. Em seguida, implemente NativeAdListener para receber callbacks de eventos de anúncios.

class NativeExampleState extends State<NativeExample> {
  NativeAd? _nativeAd;
  bool _nativeAdIsLoaded = false;

 // TODO: replace this test ad unit with your own ad unit.
 final String _adUnitId = Platform.isAndroid
      ? 'ca-app-pub-3940256099942544/2247696110'
      : 'ca-app-pub-3940256099942544/3986624511';

  /// Loads a native ad.
  void loadAd() {
    _nativeAd = NativeAd(
        adUnitId: _adUnitId,
        // Factory ID registered by your native ad factory implementation.
        factoryId: 'adFactoryExample',
        listener: NativeAdListener(
          onAdLoaded: (ad) {
            print('$NativeAd loaded.');
            setState(() {
              _nativeAdIsLoaded = true;
            });
          },
          onAdFailedToLoad: (ad, error) {
            // Dispose the ad here to free resources.
            print('$NativeAd failedToLoad: $error');
            ad.dispose();
          },
          // Called when a click is recorded for a NativeAd.
          onAdClicked: (ad) {},
          // Called when an impression occurs on the ad.
          onAdImpression: (ad) {},
          // Called when an ad removes an overlay that covers the screen.
          onAdClosed: (ad) {},
          // Called when an ad opens an overlay that covers the screen.
          onAdOpened: (ad) {},
          // For iOS only. Called before dismissing a full screen view
          onAdWillDismissScreen: (ad) {},
          // Called when an ad receives revenue value.
          onPaidEvent: (ad, valueMicros, precision, currencyCode) {},
        ),
        request: const AdRequest(),
        // Optional: Pass custom options to your native ad factory implementation.
        customOptions: {'custom-option-1', 'custom-value-1'}
    );
    _nativeAd.load();
        
  }
}

Anúncio de display

Para mostrar um NativeAd como um widget, é necessário instanciar um AdWidget com um anúncio compatível depois de chamar load(). É possível criar o widget antes de chamar load(), mas load() precisa ser chamado antes de ser adicionado à árvore de widgets.

O AdWidget herda da classe Widget do Flutter e pode ser usado como qualquer outro widget. No iOS, coloque o widget em um contêiner com largura e altura especificadas. Caso contrário, seu anúncio pode não ser exibido.

final Container adContainer = Container(
  alignment: Alignment.center,
  child: AdWidget adWidget = AdWidget(ad: _nativeAd!),
  width: WIDTH,
  height: HEIGHT,
);

Excluir anúncio

Uma NativeAd precisa ser descartada quando o acesso a ela não for mais necessário. A prática recomendada para chamar dispose() é depois que o AdWidget associado ao anúncio nativo é removido da árvore de widgets e no callback AdListener.onAdFailedToLoad().

Próximas etapas

Exemplo completo no GitHub

Plataforma nativa