Gli annunci nativi vengono presentati agli utenti utilizzando componenti dell'interfaccia utente nativi della piattaforma, ad esempio un View
su Android o un UIView
su iOS.
Questa guida illustra come caricare, visualizzare e personalizzare gli annunci nativi utilizzando codice specifico per la piattaforma.
Prerequisiti
- Completa la Guida introduttiva.
- Acquisisci familiarità con le opzioni per gli annunci nativi.
Esegui sempre test con annunci di prova
Quando crei e testi le tue app, assicurati di utilizzare annunci di prova anziché annunci pubblicati in produzione. Il modo più semplice per caricare gli annunci di prova è utilizzare il nostro ID unità pubblicitaria di prova dedicato per gli annunci nativi:
Android
ca-app-pub-3940256099942544/2247696110
iOS
ca-app-pub-3940256099942544/3986624511
Le unità pubblicitarie di prova sono configurate per restituire annunci di prova per ogni richiesta, quindi puoi utilizzarle nelle tue app durante la programmazione, i test e il debug. Assicurati solo di sostituirle con i tuoi ID unità pubblicitarie prima di pubblicare l'app.
Configurazioni specifiche della piattaforma
Per creare gli annunci nativi, devi scrivere codice specifico per la piattaforma per iOS e Android, quindi modificare l'implementazione di Dart per sfruttare le modifiche al codice nativo apportate.
Android
Importa il plug-in
L'implementazione di 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 a 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
}
Implementare NativeAdFactory
Poi, crea una classe che implementi NativeAdFactory
e sostituisca il 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 the Google Mobile Ads SDK 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 chiamata
MainActivity.configureFlutterEngine(FlutterEngine)
. factoryId
verrà utilizzato in un secondo momento durante l'inizializzazione di un annuncio nativo dal codice Dart.
Un NativeAdFactory
può essere implementato e registrato per ogni layout dell'annuncio nativo univoco utilizzato dalla tua app oppure un singolo NativeAdFactory
può gestire tutti i layout.
Tieni presente che, durante la creazione con
Aggiungi all'app, anche il
NativeAdFactory
deve essere annullato la registrazione 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
Implementare 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 per inizializzare un annuncio nativo
dal codice Dart.
Un FLTNativeAdFactory
può essere implementato e registrato per ogni layout dell'annuncio nativo univoco utilizzato dalla tua app oppure un singolo FLTNativeAdFactory
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 della 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 una notifica degli eventi relativi alle interazioni con gli annunci nativi, utilizza la proprietà
listener
dell'annuncio. Poi, implementa
NativeAdListener
per ricevere i callback degli eventi correlati agli 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 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, il tuo annuncio potrebbe non essere visualizzato.
final Container adContainer = Container(
alignment: Alignment.center,
child: AdWidget adWidget = AdWidget(ad: _nativeAd!),
width: WIDTH,
height: HEIGHT,
);
Rimuovere l'annuncio
Un
NativeAd
deve essere smaltito quando non è più necessario accedervi. La best practice per sapere quando chiamare dispose()
è dopo che AdWidget
associato all'annuncio nativo è stato rimosso dall'albero dei widget e nel callback AdListener.onAdFailedToLoad()
.
Passaggi successivi
- Scopri di più sugli annunci nativi nel nostro playbook s sugli annunci nativi.
- Consulta le norme e linee guida sugli annunci nativi.
- Dai un'occhiata ad alcune storie di successo dei clienti: case study 1, case study 2.