Gli annunci nativi vengono presentati agli utenti utilizzando componenti UI nativi della piattaforma, ad esempio un View su Android o un UIView su iOS.
Questa guida mostra come caricare, visualizzare e personalizzare gli annunci nativi utilizzando il codice specifico della piattaforma.
Prerequisiti
Prima di continuare, completa queste operazioni:
Esegui sempre i test con gli annunci di prova
Durante la creazione e il test delle tue app, assicurati di utilizzare annunci di prova anziché annunci di prodotto. Il modo più semplice per caricare annunci di prova è utilizzare il nostro ID unità pubblicitaria di test dedicato per gli annunci nativi:
Android
ca-app-pub-3940256099942544/2247696110
iOS
ca-app-pub-3940256099942544/3986624511
Le unità pubblicitarie di test sono configurate per restituire annunci di test per ogni richiesta, quindi puoi utilizzarle nelle tue app durante la programmazione, il test e il debug. Assicurati di sostituirle con i tuoi ID unità pubblicitaria prima di pubblicare l'app.
Configurazioni specifiche per piattaforma
Per creare gli annunci nativi, dovrai scrivere un codice specifico per la piattaforma per iOS e Android, quindi modificare l'implementazione di Dart per sfruttare le modifiche al codice nativo che hai apportato.
Android
Importa il plug-in
L'implementazione Android del plug-in Google Mobile Ads richiede una classe che implementi l'API NativeAdFactory. Per fare riferimento a questa API dal tuo progetto Android, aggiungi le seguenti righe al file 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
}
Implementa NativeAdFactory
Successivamente, crea una classe che implementi NativeAdFactory ed esegua l'override del metodo 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 Google Mobile Ads Flutter Plugin that you have finished populating your
// native ad view with this native ad.
adView.setNativeAd(nativeAd);
return adView;
}
}
Per un esempio di configurazione del layout NativeAdView, consulta my_native_ad.xml.
Registra NativeAdFactory
Ogni implementazione di NativeAdFactory deve essere registrata con un factoryId, un identificatore String univoco, quando viene chiamato MainActivity.configureFlutterEngine(FlutterEngine). factoryId verrà utilizzato in un secondo momento durante la creazione di un'istanza di un annuncio nativo dal codice Dart.
È possibile implementare e registrare un NativeAdFactory per ogni layout dell'annuncio
nativo univoco utilizzato dalla tua app oppure un singolo può gestire tutti i layout.
Tieni presente che, quando crei con
add-to-app, devi annullare la registrazione di
NativeAdFactory anche in
cleanUpFlutterEngine(engine).
Dopo aver creato NativeAdFactoryExample, configura MainActivity come segue:
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
Implementa NativeAdFactory
L'implementazione per iOS del plug-in Google Mobile Ads richiede una classe che implementi l'API FLTNativeAdFactory. Crea una classe che implementi NativeAdFactory e implementa il metodo 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
Per un esempio di configurazione del layout GADNativeAdView, consulta NativeAdView.xib.
Registra NativeAdFactory
Ogni FLTNativeAdFactory deve essere registrato con un factoryId, un identificatore String univoco, in registerNativeAdFactory:factoryId:nativeAdFactory:.
factoryId verrà utilizzato in un secondo momento durante la creazione di un'istanza di un annuncio nativo dal codice Dart.
È possibile implementare e registrare un FLTNativeAdFactory per ogni layout dell'annuncio nativo
univoco utilizzato dalla tua app oppure un singolo può gestire tutti i layout.
Dopo aver creato FLTNativeAdFactory, configura AppDelegate come segue:
#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
Carica annuncio
Dopo aver aggiunto il codice specifico per la piattaforma, utilizza Dart per caricare gli annunci. Assicurati che factoryID corrisponda all'ID che hai registrato in precedenza.
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();
}
}
Eventi degli annunci nativi
Per ricevere notifiche sugli eventi correlati alle interazioni con gli annunci nativi, utilizza la proprietà listener dell'annuncio. Poi, implementa
NativeAdListener
per ricevere i callback degli eventi degli annunci.
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();
}
}
Annuncio display
Per visualizzare un NativeAd come widget, devi creare un'istanza di un
AdWidget
con un annuncio supportato dopo aver chiamato load(). Puoi creare il widget prima di chiamare load(), ma load() deve essere chiamato prima di aggiungerlo all'albero dei widget.
AdWidget eredita dalla classe Widget di Flutter e può essere utilizzato come qualsiasi altro widget. Su iOS, assicurati di posizionare il widget in un contenitore con larghezza e altezza specificate. In caso contrario, l'annuncio potrebbe non essere visualizzato.
final Container adContainer = Container(
alignment: Alignment.center,
child: AdWidget adWidget = AdWidget(ad: _nativeAd!),
width: WIDTH,
height: HEIGHT,
);
Elimina annuncio
Un
NativeAd
deve essere smaltito quando l'accesso non è più necessario. La best practice per
chiamare dispose() è dopo che l'elemento AdWidget associato all'annuncio nativo
viene rimosso dall'albero dei widget e nel callback
AdListener.onAdFailedToLoad().
Passaggi successivi
- Scopri di più sugli annunci nativi nel nostro playbook sugli annunci nativi.
- Consulta le norme e linee guida relative agli annunci nativi.
- Dai un'occhiata ad alcune storie di successo dei clienti: case study 1, case study 2.
Esempio completo su GitHub
Per visualizzare l'esempio completo, consulta la demo dell'API.