This native implementation is specifically designed to fit feed views
You can customize the native ad view to have the same look and feel as the other views of your feed, it will offer an immersive experience.
Integration
Important
Make sure you are using a dedicated native placement id (PID) on native ad requests, do not reuse inRead PID. You will not receive any ad if the PID is not a native one.
You are responsible for positioning the elements (title label, main image, call to action button…)
These elements need to be visible (without overlay, even transparent ones) otherwise our visibility algorithm will consider the ad view as hidden
The article is using the Native display test PID 124859. This PID is meant to be used for testing purposes and shall not be released into production.
Interface
The native ad view should be done specifically on each platform.
iOS TeadsNativeAdView
The easiest way is by creating a XIB file.
- Change the root View class type to
TeadsNativeAdView
. - Create your custom layout.
- Link all the UI elements to the corresponding native asset.
- Create a new class file which inherit from
FLTTeadsNativeAdViewFactoryProtocol
.
import TeadsSDK
import teads_sdk_flutter
class TeadsNativeAdViewFactory: FLTTeadsNativeAdViewFactoryProtocol {
func teadsNativeAdView() -> TeadsNativeAdView? {
guard let nibView = Bundle.main.loadNibNamed("TeadsNativeAdView", owner: nil, options: nil)?.first,
let nativeAdView = nibView as? TeadsNativeAdView else {
return nil
}
// Additional UI modifications
// media view
nativeAdView.mediaView?.layer.cornerRadius = 20
nativeAdView.mediaView?.layer.masksToBounds = true
// call to action
nativeAdView.callToActionButton?.layer.cornerRadius = 16
// icon
nativeAdView.iconImageView?.layer.cornerRadius = 30
return nativeAdView
}
}
- In your
AppDelegate
, register the native ad view factory.
import UIKit
import Flutter
import teads_sdk_flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
let nativeAdViewFactory = TeadsNativeAdViewFactory()
FLTTeadsSDKFlutterPlugin.registerNativeAdViewFactory(registry: self, factoryId: "exampleNativeAd", nativeAdViewFactory: nativeAdViewFactory)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Android NativeAdView
- Create a new Android resource file.
- Select Layout as the resource type, and enter tv.teads.sdk.renderer.NativeAdView as a root element.
- Implement the ad layout as matching the visual design of the user experience for the platform it's intended for.
<?xml version="1.0" encoding="utf-8"?>
<tv.teads.sdk.renderer.NativeAdView
android:id="@+id/nativeAdView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/teads_native_title"
...
/>
<ImageView
android:id="@+id/teads_native_media"
...
/>
</tv.teads.sdk.renderer.NativeAdView>
- Match the correct native elements' id.
Native View layout ids
- R.id.teads_native_title (TextView) (Guaranteed in every request)
- R.id.teads_native_content (TextView)
- R.id.teads_native_media (MediaView) (Guaranteed in every request)
- R.id.teads_native_icon (ImageView)
- R.id.teads_native_advertiser (TextView)
- R.id.teads_native_call_to_action (Button)
- R.id.teads_native_star_rating (View)
- R.id.teads_native_price (TextView)
- Create a new class file which inherit from
FLTNativeAdViewFactoryInterface
.
class TeadsNativeAdViewFactory(private val context: Context?): FLTNativeAdViewFactoryInterface {
override fun teadsNativeAdView(): NativeAdView {
return LayoutInflater.from(context)
.inflate(R.layout.teads_native_ad_view, null) as NativeAdView
}
}
- In your
MainActivity
, register/unregister the above factory as follows.
class MainActivity: FlutterFragmentActivity() {
private val factoryId = "exampleNativeAd"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
TeadsSdkFlutterPlugin.registerNativeAdViewFactory(factoryId, TeadsNativeAdViewFactory(context))
}
override fun cleanUpFlutterEngine(flutterEngine: FlutterEngine) {
super.cleanUpFlutterEngine(flutterEngine)
TeadsSdkFlutterPlugin.unregisterNativeAdViewFactory(factoryId)
}
}
Your activity superclass
Ensure to extend your activity from FlutterFragmentActivity
and not from FlutterActivity
. The first one is better bound to Teads context lifecycle.
Load an Ad
You need to create a placement first using Teads.createNativePlacement
, this placement is linked to your PID.
Important
Instance of
TeadsNativeAdPlacement
must be owned / retained in order to be able to request ads properly.
class _NativeState extends State<Native> implements TeadsNativeAdPlacementDelegate {
TeadsNativeAdView _nativeAdView = TeadsNativeAdView(factoryId: 'exampleNativeAd');
TeadsNativeAdPlacement? _placement;
@override
void initState() {
super.initState();
_initTeadsAd();
}
@override
void dispose() {
super.dispose();
// Release memory object on activity/controller dallocation
_nativeAdView.clean();
}
Future<void> _initTeadsAd() async {
TeadsAdPlacementSettings placementSettings = TeadsAdPlacementSettings();
await placementSettings.enableDebug();
_placement = await Teads.createNativePlacement(124859, placementSettings, this);
TeadsAdRequestSettings requestSettings = TeadsAdRequestSettings();
await _placement?.requestAd(requestSettings);
if (!mounted) return;
}
@override
void didReceiveAd(TeadsNativeAd ad) {
_nativeAdView.bind(ad);
}
@override
void didFailToReceiveAd(String reason) {
// Do something
}
...
}
Event Monitoring
The Teads inApp SDK provides a set of listeners to let you monitor a large scope of events all along ad life cycle.
This helps tailor the ad experience in your app.
mixin TeadsInReadAdPlacementDelegate {
// When the Teads inApp SDK has received an ad for you to display
void didReceiveAd(TeadsNativeAd ad);
// When Teads inApp SDK has failed to retrieve an ad
void didFailToReceiveAd(String reason);
}
The SDK provides a delegate to monitor events during the ad life cycle and help you customize the ad experience in your apps.
mixin TeadsAdDelegate {
// When the ad experience has experienced an issue
void didCatchError(TeadsAd ad, FlutterError error);
// When the ad has been closed
void didClose(TeadsAd ad);
// When an impression has occured
void didRecordImpression(TeadsAd ad);
// When an event click has been fired
void didRecordClick(TeadsAd ad);
// When the ad goes to fullscreen
void didExpandedToFullscreen(TeadsAd ad);
// When the ad collapse from fullscreen
void didCollapsedFromFullscreen(TeadsAd ad);
}
You can also monitor playback events thanks to the TeadsPlaybackDelegate
.
mixin TeadsPlaybackDelegate {
// When the ad has started playing audio
void adStartPlayingAudio(TeadsAd ad);
// When the ad has stopped playing audio
void adStopPlayingAudio(TeadsAd ad);
// When the ad has started playing
void didPlay(TeadsAd ad);
// When the ad has stopped playing
void didPause(TeadsAd ad);
// When the ad has complete
void didComplete(TeadsAd ad);
}
Check list
- ✅ Ensure you comply with privacy legal requirements (GDPR/CCPA).
- ✅ Comply with app-ads.txt
- ✅ Enable validation mode to ensure key features are working
Additional Settings
Find the full available TeadsAdPlacementSettings
and TeadsAdRequestSettings
settings here.