Skip to content

Native

The native ads are a kind of ad that can be shown using the same visual style like the rest of the app, which allows a natural and non-intrusive integration with the user interface.

Unlike the other formats, the ad view is defined natively on each platform and the SDK fills it with the assets of the ad, no matter which demand source has filled it. Flutter then displays that view through the AdWidget widget.

Each ad view is provided by a factory that is registered natively with an identifier, which is later used from Dart to request the ads.

First, create a layout file (for example native_ad.xml) where each view that will show an asset of the ad has an identifier, and then implement the NativeAdViewFactory interface:

package com.example.app
import android.content.Context
import com.wortise.ads.flutter.natives.NativeAdViewFactory
import com.wortise.ads.natives.NativeAdView
import com.wortise.ads.natives.NativeAdViewBinder
class MyNativeAdViewFactory(private val context: Context) : NativeAdViewFactory {
private val binder = NativeAdViewBinder.Builder(R.layout.native_ad)
.setAdvertiserTextViewId(R.id.ad_advertiser)
.setBodyTextViewId(R.id.ad_body)
.setCallToActionButtonId(R.id.ad_call_to_action)
.setHeadlineTextViewId(R.id.ad_headline)
.setIconImageViewId(R.id.ad_app_icon)
.setMediaContentViewId(R.id.ad_media)
.setPriceTextViewId(R.id.ad_price)
.setRatingContentViewId(R.id.ad_rating)
.setStoreTextViewId(R.id.ad_store)
.build()
override fun createNativeAdView() = NativeAdView(context, binder)
}

Then, register the factory in the MainActivity class:

import com.wortise.ads.flutter.natives.NativeAdManager
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
class MainActivity : FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
NativeAdManager.registerAdViewFactory("my-factory", MyNativeAdViewFactory(this))
}
override fun cleanUpFlutterEngine(flutterEngine: FlutterEngine) {
super.cleanUpFlutterEngine(flutterEngine)
NativeAdManager.unregisterAdViewFactory("my-factory")
}
}

Create a XIB file (for example NativeAdView.xib), set WANativeAdView as the class of its root view, connect the outlets of the assets that the design displays, and then implement the WortiseNativeAdViewFactory protocol:

import WortiseSDK
import wortise
class MyNativeAdViewFactory: WortiseNativeAdViewFactory {
func createNativeAdView() -> WANativeAdView {
return Bundle.main.loadNibNamed(
"NativeAdView", owner: nil
)!.first as! WANativeAdView
}
}

Then, register the factory in the AppDelegate class:

override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
WortiseNativeAdManager.registerAdViewFactory(
"my-factory", factory: MyNativeAdViewFactory()
)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

Once the factories are registered, the ads are requested with the NativeAdLoader class and displayed with the AdWidget widget:

import 'package:wortise/wortise.dart';
/* ... */
NativeAdLoader? _nativeAdLoader;
NativeAd? _nativeAd;
Widget? _nativeWidget;
@override
void initState() {
super.initState();
_nativeAdLoader = NativeAdLoader(
'Wortise Ad Unit ID',
'my-factory',
(event, args) {
if (event == NativeAdEvent.LOADED) {
final ad = args['ad'] as NativeAd;
setState(() {
_nativeAd = ad;
_nativeWidget = AdWidget(ad: ad);
});
}
},
);
_nativeAdLoader?.loadAd();
}
@override
void dispose() {
_nativeAd?.destroy();
_nativeAdLoader?.destroy();
super.dispose();
}

The widget must be placed inside a container with a defined size, in the same way as the banners:

Container(
height: 300,
child: _nativeWidget,
)

The listener receives the following events, declared in the NativeAdEvent enum:

EventDescription
CLICKEDThe ad has been clicked
FAILEDThe ad could not be loaded (because of an error or no fill)
IMPRESSIONThe ad has generated an impression
LOADEDThe ad has been loaded, and is received in the ad argument
REVENUE_PAIDThe ad has generated revenue

The loadAd method also accepts a RequestParameters instance, in the same way as the rest of the formats:

_nativeAdLoader?.loadAd(
requestParameters: RequestParameters(agent: 'your agent'),
);

If your app already integrated the deprecated GoogleNativeAd class, these are the equivalences with the new integration:

DeprecatedReplacement
GoogleNativeAd(adUnitId, factoryId, listener)NativeAdLoader(adUnitId, factoryId, listener)
GoogleNativeAdEventNativeAdEvent
load()loadAd() (or loadAd(requestParameters:))
AdWidget(ad: googleNativeAd)AdWidget(ad: nativeAd) — the ad from the LOADED event
GoogleNativeAdFactory (Android)NativeAdViewFactory
GoogleNativeAdManager (Android)NativeAdManager

The most relevant difference is which object is displayed: the deprecated class was itself passed to the AdWidget widget, whereas now the loader delivers a NativeAd in the LOADED event and that is the object to display.

_googleNativeAd = GoogleNativeAd('Wortise Ad Unit ID', 'my-factory', (event, args) {
if (event == GoogleNativeAdEvent.LOADED) {
setState(() => _nativeWidget = AdWidget(ad: _googleNativeAd!));
}
});
_googleNativeAd?.load();
_nativeAdLoader = NativeAdLoader('Wortise Ad Unit ID', 'my-factory', (event, args) {
if (event == NativeAdEvent.LOADED) {
final ad = args['ad'] as NativeAd;
setState(() => _nativeWidget = AdWidget(ad: ad));
}
});
_nativeAdLoader?.loadAd();