1. Introduction
In this codelab, you implement an AdMob banner and an AdMob native inline ad in a Flutter app.
What you'll build
This codelab guides you through implementing an AdMob inline banner and AdMob native inline ads in a Flutter app using the Google Mobile Ads plugin for Flutter.
If you have any issues (code bugs, grammatical errors, unclear wording, and so on) as you work through this codelab, report the issue using the Report a mistake link in the lower, left corner of the codelab.
What you'll learn
- How to configure the Google Mobile Ads Flutter plugin
- How to implement an inline banner and rewarded ads in a Flutter app
What you'll need
- Android Studio 4.1 or later
- Xcode 12 or later (for iOS development)
How would you rate your level of experience with AdMob?
How would you rate your level of experience with Flutter?
2. Set up your Flutter development environment
You need two pieces of software to complete this lab—the Flutter SDK and an editor.
You can run the codelab using any of these devices:
- A physical Android or iOS device connected to your computer and set to Developer mode.
- The iOS simulator (requires installing Xcode tools).
- The Android Emulator (requires setup in Android Studio).
- A browser (Chrome is required for debugging).
- As a Windows, Linux, or macOS desktop application. You must develop on the platform where you plan to deploy. So, if you want to develop a Windows desktop app, you must develop on Windows to access the appropriate build chain. There are operating system-specific requirements that are covered in detail on docs.flutter.dev/desktop.
Download the code
After you download the zip file, extract its contents. You will have a folder named admob-inline-ads-in-flutter-main
.
Alternatively, you can clone the GitHub repository from the command line:
$ git clone https://github.com/googlecodelabs/admob-inline-ads-in-flutter
The repository contains three folders:
- starter: Starting code that you will build in this codelab.
- complete: Completed code for this codelab. (Java & Objective-C for native code)
- complete_kotlin_swift: Completed code for this codelab. (Kotlin & Swift for native code)
3. Set up AdMob app and ad units
Because Flutter is a multi-platform SDK, you need to add an app and ad units for both Android and iOS in AdMob.
Set up for Android
To set up for Android, you need to add an Android app and create ad units.
Add an Android app
- In the AdMob console, click ADD APP from the Apps menu.
- When you're asked Have you published your app on Google Play or the App Store?, click NO.
- Enter
AdMob inline ads
in the app name field, and select Android as the platform.
- Enabling user metrics is not necessary to complete this codelab. However, we recommend that you do because it allows you to understand user behavior in more detail. Click ADD to complete the process.
Create ad units
To add ad units:
- Select AdMob inline ads app from Apps menu in the AdMob console.
- Click the Ad units menu.
Banner
|
Native
|
It usually takes a few hours for a new ad unit to be able to serve ads.
If you want to test the ad's behavior immediately, then use the test app ID and ad unit IDs listed in the Android app ID/ad unit ID and iOS app ID/ad unit ID tables.
Set up for iOS
To set up for iOS, you need to add an iOS app and create ad units.
Add an iOS app
- In the AdMob console, click ADD APP from the Apps menu.
- When you're asked Have you published your app on Google Play or the App Store?, click NO.
- Enter
AdMob inline ads
in the app name field, and select iOS as the platform.
- Enabling user metrics is not necessary to complete this codelab. However, we recommend that you do because it allows you to understand user behavior in more detail. Click ADD to complete the process.
Create ad units
To add ad units:
- Select AdMob inline ads app from Apps menu in the AdMob console.
- Click the Ad units menu.
Banner
|
Native
|
It usually takes a few hours for a new ad unit to be able to serve ads.
If you want to test the ad's behavior immediately, then use the test app ID and ad unit IDs listed in the following table.
Optional: Use the test AdMob app and ad units
If you want to follow the codelab instead of creating a new application and ad units on your own, you can use the test AdMob app ID and ad unit IDs listed in the following tables.
Android app ID/ad unit ID
Item | app ID/ad unit ID |
AdMob app ID |
|
Banner |
|
Native |
|
iOS app ID/ad unit ID
Item | app ID/ad unit ID |
AdMob app ID |
|
Banner |
|
Native |
|
For more information about the test ads, see the Android test ads and the iOS test ads developer documentation.
4. Add the Google Mobile Ads Flutter plugin
Flutter uses plugins to provide access to a wide range of platform-specific services. Plugins enable you to access services and APIs on each platform.
The google_mobile_ads plugin supports loading and displaying banner, interstitial, rewarded, and native ads using the AdMob API.
Because Flutter is a multi-platform SDK, the google_mobile_ads plugin is applicable for both iOS and Android. So, if you add the plugin to your Flutter app, it's used by both Android and iOS versions of the AdMob inline ads app.
Add the Google Mobile Ads plugin as a dependency
To access the AdMob APIs from the AdMob inline ads project, add google_mobile_ads
as a dependency to the pubspec.yaml
file located at the root of the project.
pubspec.yaml
...
dependencies:
flutter:
sdk: flutter
google_fonts: ^0.3.9
# TODO: Add google_mobile_ads as a dependency
google_mobile_ads: ^1.2.0
...
Click Pub get to install the plugin in the AdMob inline ads project.
Update AndroidManifest.xml (Android)
- Open the
android/app/src/main/AndroidManifest.xml
file in Android Studio. - Add your AdMob app ID by adding a
<meta-data>
tag with the namecom.google.android.gms.ads.APPLICATION_ID
. For example, if your AdMob app ID isca-app-pub-3940256099942544~3347511713
, then you need to add the following lines to theAndroidManifest.xml
file.
AndroidManifest.xml
<manifest>
...
<application>
...
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~3347511713"/>
</application>
</manifest>
Update Info.plist (iOS)
- Open the
ios/Runner/Info.plist
file in Android Studio. - Add a
GADApplicationIdentifier
key with the string value of your AdMob app ID. For example, if your AdMob app ID isca-app-pub-3940256099942544~1458002511
, then you need to add the following lines to theInfo.plist
file.
ios/Runner/Info.plist
...
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-3940256099942544~1458002511</string>
...
5. Add a helper class for ads
Create a new file named ad_helper.dart
under the lib
directory. Then, implement the AdHelper
class, which provides an AdMob app ID and ad unit IDs for Android and iOS.
Make sure that you replace the AdMob app ID (ca-app-pub-xxxxxx~yyyyy
) and the ad unit ID (ca-app-pub-xxxxxxx/yyyyyyyy
) with the IDs you created in the previous step.
ad_helper.dart
import 'dart:io';
class AdHelper {
static String get bannerAdUnitId {
if (Platform.isAndroid) {
return "<YOUR_ANDROID_BANNER_AD_UNIT_ID";
} else if (Platform.isIOS) {
return "<YOUR_IOS_BANNER_AD_UNIT_ID>";
} else {
throw UnsupportedError("Unsupported platform");
}
}
static String get nativeAdUnitId {
if (Platform.isAndroid) {
return "<YOUR_ANDROID_NATIVE_AD_UNIT_ID>";
} else if (Platform.isIOS) {
return "<YOUR_IOS_NATIVE_AD_UNIT_ID>";
} else {
throw UnsupportedError("Unsupported platform");
}
}
}
Use the following code snippet if you want to use the test AdMob app ID and test ad unit IDs.
ad_helper.dart
import 'dart:io';
class AdHelper {
static String get bannerAdUnitId {
if (Platform.isAndroid) {
return 'ca-app-pub-3940256099942544/6300978111';
} else if (Platform.isIOS) {
return 'ca-app-pub-3940256099942544/2934735716';
}
throw UnsupportedError("Unsupported platform");
}
static String get nativeAdUnitId {
if (Platform.isAndroid) {
return 'ca-app-pub-3940256099942544/2247696110';
} else if (Platform.isIOS) {
return 'ca-app-pub-3940256099942544/3986624511';
}
throw UnsupportedError("Unsupported platform");
}
}
6. Initialize the Google Mobile Ads SDK
Before loading ads, you need to initialize the Google Mobile Ads SDK. Open the lib/home_page.dart
file, and modify _initGoogleMobileAds()
to initialize the SDK before the home page is loaded.
Note that you need to change the return type of the _initGoogleMobileAds()
method from Future<dynamic>
to Future<InitializationStatus>
to get the SDK initialization result after it completes.
home_page.dart
// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:flutter/material.dart';
...
class HomePage extends StatelessWidget {
...
Future<InitializationStatus> _initGoogleMobileAds() {
// TODO: Initialize Google Mobile Ads SDK
return MobileAds.instance.initialize();
}
}
7. Add a banner ad
In this section, you display a banner ad in the middle of the list, as shown in the following screenshot.
- Open the
lib/banner_inline_page.dart
file. - Import
ad_helper.dart
andgoogle_mobile_ads.dart
by adding the following lines:
banner_inline_page.dart
...
// TODO: Import ad_helper.dart
import 'package:admob_inline_ads_in_flutter/ad_helper.dart';
// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';
class BannerInlinePage extends StatefulWidget {
...
}
- In the
_BannerInlinePageState
class, add the following members and methods for a banner ad.
Note that _kAdIndex
indicates the index where a banner ad will be displayed, and it's used to calculate the item index from the _getDestinationItemIndex()
method.
banner_inline_page.dart
class _BannerInlinePageState extends State<BannerInlinePage> {
// TODO: Add _kAdIndex
static final _kAdIndex = 4;
// TODO: Add a banner ad instance
BannerAd? _ad;
...
// TODO: Add _getDestinationItemIndex()
int _getDestinationItemIndex(int rawIndex) {
if (rawIndex >= _kAdIndex && _ad != null) {
return rawIndex - 1;
}
return rawIndex;
}
...
}
- In the
initState()
method, create and load aBannerAd
for the 320x50 banner (AdSize.banner
). Note that an ad event listener is configured to update the UI (setState()
) when an ad is loaded.
banner_inline_page.dart
@override
void initState() {
super.initState();
// TODO: Load a banner ad
BannerAd(
adUnitId: AdHelper.bannerAdUnitId,
size: AdSize.banner,
request: AdRequest(),
listener: BannerAdListener(
onAdLoaded: (ad) {
setState(() {
_ad = ad as BannerAd;
});
},
onAdFailedToLoad: (ad, error) {
// Releases an ad resource when it fails to load
ad.dispose();
print('Ad load failed (code=${error.code} message=${error.message})');
},
),
).load();
}
- Modify the
build()
method to display a banner ad when available. - Update
itemCount,
to count a banner ad entry, and updateitemBuilder,
to render a banner ad at the ad index (_kAdIndex
) when the ad is loaded. - Update the code to use the
_getDestinationItemIndex()
method to retrieve an index for the content item.
banner_inline_page.dart
@override
Widget build(BuildContext context) {
return Scaffold(
...
body: ListView.builder(
// TODO: Adjust itemCount based on the ad load state
itemCount: widget.entries.length + (_ad != null ? 1 : 0),
itemBuilder: (context, index) {
// TODO: Render a banner ad
if (_ad != null && index == _kAdIndex) {
return Container(
width: _ad!.size.width.toDouble(),
height: 72.0,
alignment: Alignment.center,
child: AdWidget(ad: _ad!),
);
} else {
// TODO: Get adjusted item index from _getDestinationItemIndex()
final item = widget.entries[_getDestinationItemIndex(index)];
return ListTile(
...
);
}
},
),
);
}
- Release the resource associated with the
BannerAd
object by calling theBannerAd.dispose()
method in thedispose()
callback method.
banner_inline_page.dart
@override
void dispose() {
// TODO: Dispose a BannerAd object
_ad?.dispose();
super.dispose();
}
That's it! Run the project, and click the Banner inline ad button from the home page. After an ad is loaded, you'll see a banner ad in the middle of the list.
8. Add a native ad
In this section, you display a native ad in the middle of the list, as shown in the following screenshot.
Native ads are presented to users using UI components that are native to the platform (for example, View
on Android or UIView
on iOS).
However, it isn't possible to create native UI components directly by using Flutter widgets. So, you have to implement a NativeAdFactory
for each platform, which is used to build a platform-specific native ad view (NativeAdView
on Android and GADNativeAdView
on iOS) from a native ad object (NativeAd
on Android and GADNativeAd
on iOS).
Implement NativeAdFactory for Android (Java)
- Open the
android/build.gradle
file (or any file under the android folder), and click Open for Editing in Android Studio to open an Android project.
- If you're asked to select a window to open a new project, click New Window to make the Flutter project remain open while you're working on the Android project.
Create a native ad layout
- With the Android project opened, right-click app from the project pane in Android Studio, and select New > Android Resource File from the context menu.
- In the New Resource File dialog, enter
list_tile_native_ad.xml
as the file name. - Select Layout as the resource type, and enter
com.google.android.gms.ads.nativead.NativeAdView
as a root element. - Click OK to create a new layout file.
- Implement the ad layout as follows. Note that the layout should match the visual design of the user experience for the platform it's intended for.
list_tile_native_ad.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_list_tile_native_ad_attribution_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#F19938"
android:text="Ad"
android:textColor="#FFFFFF"
android:textSize="12sp" />
<ImageView
android:id="@+id/iv_list_tile_native_ad_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:scaleType="fitXY"
tools:background="#EDEDED" />
<TextView
android:id="@+id/tv_list_tile_native_ad_attribution_large"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:background="#F19938"
android:gravity="center"
android:text="Ad"
android:textColor="#FFFFFF"
android:visibility="invisible" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="80dp"
android:layout_marginLeft="80dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_list_tile_native_ad_headline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:textColor="#000000"
android:textSize="16sp"
tools:text="Headline" />
<TextView
android:id="@+id/tv_list_tile_native_ad_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:textColor="#828282"
android:textSize="14sp"
tools:text="body" />
</LinearLayout>
</FrameLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
Create the ListTileNativeAdFactory class
- In the Project pane, right-click the com.codelab.flutter.admobinlineads package, and select New > Java Class.
- Enter
ListTileNativeAdFactory
as the name, and select Class from the list.
- After the New Class dialog appears, leave everything empty, and click OK.
You'll see that the ListTileNativeAdFactory
class is created in the package com.codelab.flutter.admobinlineads
.
- Implement the
ListTileNativeAdFactory
class as follows. Note that the class implements thecreateNativeAd()
method in theGoogleMobileAdsPlugin.NativeAdFactory
interface.
The factory class is responsible for creating a view object for rendering a native ad. As you can see from the code, the factory class creates a UnifiedNativeAdView
and populates it with a NativeAd
object.
ListTileNativeAdFactory.java
// TODO: Implement ListTileNativeAdFactory class
package com.codelab.flutter.admobinlineads;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Map;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin;
class ListTileNativeAdFactory implements GoogleMobileAdsPlugin.NativeAdFactory {
private final Context context;
ListTileNativeAdFactory(Context context) {
this.context = context;
}
@Override
public NativeAdView createNativeAd(
NativeAd nativeAd, Map<String, Object> customOptions) {
NativeAdView nativeAdView = (NativeAdView) LayoutInflater.from(context)
.inflate(R.layout.list_tile_native_ad, null);
TextView attributionViewSmall = nativeAdView
.findViewById(R.id.tv_list_tile_native_ad_attribution_small);
TextView attributionViewLarge = nativeAdView
.findViewById(R.id.tv_list_tile_native_ad_attribution_large);
ImageView iconView = nativeAdView.findViewById(R.id.iv_list_tile_native_ad_icon);
NativeAd.Image icon = nativeAd.getIcon();
if (icon != null) {
attributionViewSmall.setVisibility(View.VISIBLE);
attributionViewLarge.setVisibility(View.INVISIBLE);
iconView.setImageDrawable(icon.getDrawable());
} else {
attributionViewSmall.setVisibility(View.INVISIBLE);
attributionViewLarge.setVisibility(View.VISIBLE);
}
nativeAdView.setIconView(iconView);
TextView headlineView = nativeAdView.findViewById(R.id.tv_list_tile_native_ad_headline);
headlineView.setText(nativeAd.getHeadline());
nativeAdView.setHeadlineView(headlineView);
TextView bodyView = nativeAdView.findViewById(R.id.tv_list_tile_native_ad_body);
bodyView.setText(nativeAd.getBody());
bodyView.setVisibility(nativeAd.getBody() != null ? View.VISIBLE : View.INVISIBLE);
nativeAdView.setBodyView(bodyView);
nativeAdView.setNativeAd(nativeAd);
return nativeAdView;
}
}
Register the ListTileNativeAdFactory class
An instance of a NativeAdFactory
should be registered to the GoogleMobileAdsPlugin
before it can be used from the Flutter side.
- Open the
MainActivity.java
file, and override theconfigureFlutterEngine()
method and thecleanUpFlutterEngine()
method. - Register the
ListTileNativeAdFactory
class with a unique string ID (listTile
) in theconfigureFlutterEngine()
method.
MainActivity.java
public class MainActivity extends FlutterActivity {
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
// TODO: Register the ListTileNativeAdFactory
GoogleMobileAdsPlugin.registerNativeAdFactory(flutterEngine, "listTile",
new ListTileNativeAdFactory(getContext()));
}
...
}
- Every
NativeAdFactory
instance should be unregistered during the cleanup process. Unregister theListTileNativeAdFactory
class in thecleanUpFlutterEngine()
method.
MainActivity.java
public class MainActivity extends FlutterActivity {
...
@Override
public void cleanUpFlutterEngine(@NonNull FlutterEngine flutterEngine) {
super.cleanUpFlutterEngine(flutterEngine);
// TODO: Unregister the ListTileNativeAdFactory
GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "listTile");
}
}
Now you're ready to use the ListTileNativeAdFactory
class to render native ads on Android.
Implement NativeAdFactory for Android (Kotlin)
- Open the
android/build.gradle
file (or any file under the android folder), and click Open for Editing in Android Studio to open an Android project.
- If you're asked to select a window to open a new project, click New Window to make the Flutter project remain open while you're working on the Android project.
Create a native ad layout
- With the Android project opened, right-click app from the project pane in Android Studio, and select New > Android Resource File from the context menu.
- In the New Resource File dialog, enter
list_tile_native_ad.xml
as the file name. - Select Layout as the resource type, and enter
com.google.android.gms.ads.nativead.NativeAdView
as a root element. - Click OK to create a new layout file.
- Implement the ad layout as follows. Note that the layout should match the visual design of the user experience for the platform it's intended for.
list_tile_native_ad.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_list_tile_native_ad_attribution_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#F19938"
android:text="Ad"
android:textColor="#FFFFFF"
android:textSize="12sp" />
<ImageView
android:id="@+id/iv_list_tile_native_ad_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:scaleType="fitXY"
tools:background="#EDEDED" />
<TextView
android:id="@+id/tv_list_tile_native_ad_attribution_large"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:background="#F19938"
android:gravity="center"
android:text="Ad"
android:textColor="#FFFFFF"
android:visibility="invisible" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="80dp"
android:layout_marginLeft="80dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:orientation="vertical">
<TextView
android:id="@+id/tv_list_tile_native_ad_headline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:textColor="#000000"
android:textSize="16sp"
tools:text="Headline" />
<TextView
android:id="@+id/tv_list_tile_native_ad_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:textColor="#828282"
android:textSize="14sp"
tools:text="body" />
</LinearLayout>
</FrameLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
Create the ListTileNativeAdFactory class
- In the Project pane, right-click the com.codelab.flutter.admobinlineads package, and select New > Kotlin File/Class.
- Enter
ListTileNativeAdFactory
as the name, and select Class from the list.
- You'll see that the
ListTileNativeAdFactory
class is created in the packagecom.codelab.flutter.admobinlineads
. - Implement the
ListTileNativeAdFactory
class as follows. Note that the class implements thecreateNativeAd()
method in theGoogleMobileAdsPlugin.NativeAdFactory
interface.
The factory class is responsible for creating a view object for rendering a native ad. As you can see from the code, the factory class creates a NativeAdView
and populates it with a NativeAd
object.
ListTileNativeAdFactory.kt
// TODO: Implement ListTileNativeAdFactory class
package com.codelab.flutter.admobinlineads
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
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
class ListTileNativeAdFactory(val context: Context) : GoogleMobileAdsPlugin.NativeAdFactory {
override fun createNativeAd(
nativeAd: NativeAd,
customOptions: MutableMap<String, Any>?
): NativeAdView {
val nativeAdView = LayoutInflater.from(context)
.inflate(R.layout.list_tile_native_ad, null) as NativeAdView
with(nativeAdView) {
val attributionViewSmall =
findViewById<TextView>(R.id.tv_list_tile_native_ad_attribution_small)
val attributionViewLarge =
findViewById<TextView>(R.id.tv_list_tile_native_ad_attribution_large)
val iconView = findViewById<ImageView>(R.id.iv_list_tile_native_ad_icon)
val icon = nativeAd.icon
if (icon != null) {
attributionViewSmall.visibility = View.VISIBLE
attributionViewLarge.visibility = View.INVISIBLE
iconView.setImageDrawable(icon.drawable)
} else {
attributionViewSmall.visibility = View.INVISIBLE
attributionViewLarge.visibility = View.VISIBLE
}
this.iconView = iconView
val headlineView = findViewById<TextView>(R.id.tv_list_tile_native_ad_headline)
headlineView.text = nativeAd.headline
this.headlineView = headlineView
val bodyView = findViewById<TextView>(R.id.tv_list_tile_native_ad_body)
with(bodyView) {
text = nativeAd.body
visibility = if (nativeAd.body.isNotEmpty()) View.VISIBLE else View.INVISIBLE
}
this.bodyView = bodyView
setNativeAd(nativeAd)
}
return nativeAdView
}
}
Register the ListTileNativeAdFactory class
An instance of a NativeAdFactory
should be registered to the GoogleMobileAdsPlugin
before it can be used from the Flutter side.
- Open the
MainActivity.kt
file, and override theconfigureFlutterEngine()
method and thecleanUpFlutterEngine()
method. - Register the
ListTileNativeAdFactory
class with a unique string ID (listTile
) in theconfigureFlutterEngine()
method.
MainActivity.kt
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
// TODO: Register the ListTileNativeAdFactory
GoogleMobileAdsPlugin.registerNativeAdFactory(
flutterEngine, "listTile", ListTileNativeAdFactory(context))
}
...
}
- Every
NativeAdFactory
instance should be unregistered during the cleanup process. Unregister theListTileNativeAdFactory
class in thecleanUpFlutterEngine()
method.
MainActivity.kt
class MainActivity: FlutterActivity() {
...
override fun cleanUpFlutterEngine(flutterEngine: FlutterEngine) {
super.cleanUpFlutterEngine(flutterEngine)
// TODO: Unregister the ListTileNativeAdFactory
GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "listTile")
}
}
Now you're ready to use the ListTileNativeAdFactory
class to render native ads on Android.
Implement NativeAdFactory for iOS (Objective-C)
Open the ios/Podfile
file (or any file under the ios folder), and click Open iOS module in Xcode to open an iOS project.
Prepare a native ad layout
You'll need to have a custom view (*.xib
) for laying out native ad assets. In this codelab, the preconfigured view is used to minimize your efforts.
With the iOS project opened in Xcode, confirm that ListTileNativeAdView.xib exists in the Runner project.
Create the ListTileNativeAdFactory class
- From the project navigator, right-click the Runner group, and select New File to create a header file for the new class.
- In the template dialog, select the Header File, and name it
ListTileNativeAdFactory
. - After the
ListTileNativeAdFactory.h
file is created, define theListNativeAdFactory
class as follows:
ListTileNativeAdFactory.h
#ifndef ListTileNativeAdFactory_h
#define ListTileNativeAdFactory_h
// TODO: Import FLTGoogleMobileAdsPlugin.h
#import "FLTGoogleMobileAdsPlugin.h"
// TODO: Declare ListTileNativeAdFactory
@interface ListTileNativeAdFactory : NSObject<FLTNativeAdFactory>
@end
#endif /* ListTileNativeAdFactory_h */
- Create an Objective-C file by selecting New File from the Runner group.
- In the next dialog, enter
ListTileNativeAdFactory
in the File field, and select Empty File as the file type.
- After you click Next, you're asked to select a folder where the new file should be created. Leave everything unchanged, and click Create.
- Implement the
ListTileNativeFactory
class as follows. Note that the class implements thecreateNativeAd()
method in theFLTNativeAdFactory
protocol.
The factory class is responsible for creating a view object for rendering a native ad. As you can see from the code, the factory class creates a GADNativeAdView
and populates it with a GADNativeAd
object.
ListTileNativeAdFactory.m
// TODO: Import ListTileNativeAdFactory.h
#import "ListTileNativeAdFactory.h"
// TODO: Implement ListTileNativeAdFactory
@implementation ListTileNativeAdFactory
- (GADNativeAdView *)createNativeAd:(GADNativeAd *)nativeAd
customOptions:(NSDictionary *)customOptions {
GADNativeAdView *nativeAdView =
[[NSBundle mainBundle] loadNibNamed:@"ListTileNativeAdView" owner:nil options:nil].firstObject;
((UILabel *)nativeAdView.headlineView).text = nativeAd.headline;
((UILabel *)nativeAdView.bodyView).text = nativeAd.body;
nativeAdView.bodyView.hidden = nativeAd.body ? NO : YES;
((UIImageView *)nativeAdView.iconView).image = nativeAd.icon.image;
nativeAdView.iconView.hidden = nativeAd.icon ? NO : YES;
nativeAdView.callToActionView.userInteractionEnabled = NO;
nativeAdView.nativeAd = nativeAd;
return nativeAdView;
}
@end
Register the ListTileNativeAdFacotry class
An implementation of a FLTNativeAdFactory
should be registered to the FLTGoogleMobileAdsPlugin
before it can be used from the Flutter side.
Open the AppDelegate.m
file, and register the ListTileNativeAdFactory
with a unique string ID (listTile
) by calling the [FLTGoogleMobileAdsPlugin registerNativeAdFactory]
method.
AppDelegate.m
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
// TODO: Import ListTileNativeAdFactory.h
#import "ListTileNativeAdFactory.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// TODO: Register ListTileNativeAdFactory
ListTileNativeAdFactory *listTileFactory = [[ListTileNativeAdFactory alloc] init];
[FLTGoogleMobileAdsPlugin registerNativeAdFactory:self
factoryId:@"listTile"
nativeAdFactory:listTileFactory];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
Now you're ready to use the ListTileNativeAdFactory
to render native ads on iOS.
Implement NativeAdFactory for iOS (Swift)
Open the ios/Podfile
file (or any file under the ios folder), and click Open iOS module in Xcode to open an iOS project.
Prepare a native ad layout
You'll need to have a custom view (*.xib
) for laying out native ad assets. In this codelab, the preconfigured view is used to minimize your efforts.
With the iOS project opened in Xcode, confirm that ListTileNativeAdView.xib exists in the Runner project.
Create the ListTileNativeAdFactory class
- From the project navigator, right-click the Runner group, and select New File to create a header file for the new class.
- In the template dialog, select the Swift File, and name it
ListTileNativeAdFactory
. - After the
ListTileNativeAdFactory.swift
file is created, implement theListNativeAdFactory
class.
Note that the class implements the createNativeAd()
method in the FLTNativeAdFactory
protocol.
The factory class is responsible for creating a view object for rendering a native ad. As you can see from the code, the factory class creates a GADNativeAdView
and populates it with a GADNativeAd
object.
ListTileNativeAdFactory.swift
// TODO: Import google_mobile_ads
import google_mobile_ads
// TODO: Implement ListTileNativeAdFactory
class ListTileNativeAdFactory : FLTNativeAdFactory {
func createNativeAd(_ nativeAd: GADNativeAd,
customOptions: [AnyHashable : Any]? = nil) -> GADNativeAdView? {
let nibView = Bundle.main.loadNibNamed("ListTileNativeAdView", owner: nil, options: nil)!.first
let nativeAdView = nibView as! GADNativeAdView
(nativeAdView.headlineView as! UILabel).text = nativeAd.headline
(nativeAdView.bodyView as! UILabel).text = nativeAd.body
nativeAdView.bodyView!.isHidden = nativeAd.body == nil
(nativeAdView.iconView as! UIImageView).image = nativeAd.icon?.image
nativeAdView.iconView!.isHidden = nativeAd.icon == nil
nativeAdView.callToActionView?.isUserInteractionEnabled = false
nativeAdView.nativeAd = nativeAd
return nativeAdView
}
}
Register the ListTileNativeAdFacotry class
An implementation of a FLTNativeAdFactory
should be registered to the FLTGoogleMobileAdsPlugin
before it can be used from the Flutter side.
Open the AppDelegate.m
file, and register the ListTileNativeAdFactory
with a unique string ID (listTile
) by calling the FLTGoogleMobileAdsPlugin.registerNativeAdFactory()
method.
AppDelegate.swift
import UIKit
import Flutter
// TODO: Import google_mobile_ads
import google_mobile_ads
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
// TODO: Register ListTileNativeAdFactory
let listTileFactory = ListTileNativeAdFactory()
FLTGoogleMobileAdsPlugin.registerNativeAdFactory(
self, factoryId: "listTile", nativeAdFactory: listTileFactory)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Now you're ready to use the ListTileNativeAdFactory
to render native ads on iOS.
Integrate the native ad with Flutter widgets
- Open
lib/native_inline_page.dart
file. Then, importad_helper.dart
andgoogle_mobile_ads.dart
by adding the following lines:
native_inline_page.dart
...
// TODO: Import ad_helper.dart
import 'package:admob_inline_ads_in_flutter/ad_helper.dart';
// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';
class NativeInlinePage extends StatefulWidget {
...
}
- In
_NativeInlinePageState
class, add the following members and methods for a native ad.
Note that _kAdIndex
indicates the index where a banner ad will be displayed, and it's used to calculate the item index from the _getDestinationItemIndex()
method.
native_inline_page.dart
class _NativeInlinePageState extends State<NativeInlinePage> {
// TODO: Add _kAdIndex
static final _kAdIndex = 4;
// TODO: Add a native ad instance
NativeAd? _ad;
...
// TODO: Add _getDestinationItemIndex()
int _getDestinationItemIndex(int rawIndex) {
if (rawIndex >= _kAdIndex && _ad != null) {
return rawIndex - 1;
}
return rawIndex;
}
...
}
- In the
initState()
method, create and load aNativeAd
that usesListTileNativeAdFactory
to generate a native ad view.
Note that the same factory ID (listTile
) used to register the factory to the plugin is used.
native_inline_page.dart
@override
void initState() {
super.initState();
// TODO: Create a NativeAd instance
_ad = NativeAd(
adUnitId: AdHelper.nativeAdUnitId,
factoryId: 'listTile',
request: AdRequest(),
listener: NativeAdListener(
onAdLoaded: (ad) {
setState(() {
_ad = ad as NativeAd;
});
},
onAdFailedToLoad: (ad, error) {
// Releases an ad resource when it fails to load
ad.dispose();
print('Ad load failed (code=${error.code} message=${error.message})'); },
),
);
_ad.load();
}
- Modify the
build()
method to display a banner ad when available. - Update
itemCount,
to count a banner ad entry, and update theitemBuilder,
to render a banner ad at the ad index (_kAdIndex
) when the ad is loaded. - Update the code to use the
_getDestinationItemIndex()
method to retrieve an index for the content item.
native_inline_page.dart
@override
Widget build(BuildContext context) {
return Scaffold(
...
body: ListView.builder(
// TODO: Adjust itemCount based on the ad load state
itemCount: widget.entries.length + (_ad != null ? 1 : 0),
itemBuilder: (context, index) {
// TODO: Render a banner ad
if (_ad != null && index == _kAdIndex) {
return Container(
height: 72.0,
alignment: Alignment.center,
child: AdWidget(ad: _ad!),
);
} else {
// TODO: Get adjusted item index from _getDestinationItemIndex()
final item = widget.entries[_getDestinationItemIndex(index)];
return ListTile(
...
);
}
},
),
);
}
- Release the resource associated with the
NativeAd
object by callingNativeAd.dispose()
method in thedispose()
callback method.
native_inline_page.dart
@override
void dispose() {
// TODO: Dispose a NativeAd object
_ad?.dispose();
super.dispose();
}
That's it! Run the project, and click the Native inline ad button from the home page. After an ad is loaded, you'll see a native ad in the middle of the list.
9. All done!
You completed the codelab. You can find the completed code for this codelab in the complete or the complete_kotlin_swift folder.