Flutter Native Ad Templates Implementation
The native ad is that matches our website theme where we can change the color and font according to our website. Here we will implement it with templates which you can also use in your application.
Add the Google Mobile Ads plugin as a dependency to the pubspec.yaml file.
/pubspec.yaml
google_mobile_ads: ^1.0.1
AdMob app ID
Add the Highlighted lines to the AndroidManifest.xml
file with your own AdMob app ID.
android/app/src/main/AndroidManifest.xml
<manifest>
...
<application>
...
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~3347511713"/>
</application>
</manifest>
Change
minSdkVersion to 19
android/app/build.gradle
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.test_g_ad_2"
minSdkVersion 19
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
NativeAdFactory class for small template.
android/app/src/main/kotlin/com/example/nativetemplates/NativeAdFactorySmall.java
import com.google.android.gms.ads.nativead.MediaView;
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.Button;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import java.util.Map;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin;
class NativeAdFactorySmall implements GoogleMobileAdsPlugin.NativeAdFactory {
private final Context context;
NativeAdFactorySmall(Context context) {
this.context = context;
}
public NativeAdView createNativeAd(
NativeAd nativeAd, Map<String, Object> customOptions) {
NativeAdView nativeAdView = (NativeAdView) LayoutInflater.from(context)
.inflate(R.layout.small_template, null);
// attribution
TextView attributionViewSmall = nativeAdView
.findViewById(R.id.native_ad_attribution_small);
attributionViewSmall.setVisibility(View.VISIBLE);
// icon
nativeAdView.setIconView(nativeAdView.findViewById(R.id.native_ad_icon));
if (nativeAd.getIcon() == null) {
nativeAdView.getIconView().setVisibility(View.GONE);
} else {
((ImageView)nativeAdView.getIconView()).setImageDrawable(nativeAd.getIcon().getDrawable());
}
// media
// MediaView mediaView = nativeAdView.findViewById(R.id.native_ad_media);
// mediaView.setMediaContent(nativeAd.getMediaContent());
// nativeAdView.setMediaView(mediaView);
// button
nativeAdView.setCallToActionView(nativeAdView.findViewById(R.id.native_ad_button));
if(nativeAd.getCallToAction()==null){
nativeAdView.getCallToActionView().setVisibility(View.INVISIBLE);
}else{
((Button)nativeAdView.getCallToActionView()).setText(nativeAd.getCallToAction());
}
// headline
nativeAdView.setHeadlineView(nativeAdView.findViewById(R.id.native_ad_headline));
((TextView)nativeAdView.getHeadlineView()).setText(nativeAd.getHeadline());
// bodyView
nativeAdView.setBodyView(nativeAdView.findViewById(R.id.native_ad_body));
if(nativeAd.getBody()==null){
nativeAdView.getBodyView().setVisibility(View.INVISIBLE);
}else {
((TextView)nativeAdView.getBodyView()).setText(nativeAd.getBody());
nativeAdView.getBodyView().setVisibility(View.VISIBLE);
}
// advertiser name
nativeAdView.setAdvertiserView(nativeAdView.findViewById(R.id.native_ad_advertiser));
if(nativeAd.getAdvertiser()==null){
nativeAdView.getAdvertiserView().setVisibility(View.GONE);
}else {
((TextView)nativeAdView.getAdvertiserView()).setText(nativeAd.getAdvertiser());
nativeAdView.getAdvertiserView().setVisibility(View.VISIBLE);
}
// ratingbar
nativeAdView.setStarRatingView(nativeAdView.findViewById(R.id.native_ad_rating));
if(nativeAd.getStarRating()==null){
nativeAdView.getStarRatingView().setVisibility(View.INVISIBLE);
}else{
((RatingBar)nativeAdView.getStarRatingView()).setRating(nativeAd.getStarRating().floatValue());
nativeAdView.getStarRatingView().setVisibility(View.VISIBLE);
}
nativeAdView.setNativeAd(nativeAd);
return nativeAdView;
}
}
NativeAdFactory class for medium template.
android/app/src/main/kotlin/com/example/nativetemplates/NativeAdFactoryMedium.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import com.google.android.gms.ads.nativead.MediaView;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;
import java.util.Map;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin;
class NativeAdFactoryMedium implements GoogleMobileAdsPlugin.NativeAdFactory {
private final Context context;
NativeAdFactoryMedium(Context context) {
this.context = context;
}
public NativeAdView createNativeAd(NativeAd nativeAd, Map<String, Object> customOptions) {
NativeAdView nativeAdView = (NativeAdView) LayoutInflater.from(context)
.inflate(R.layout.medium_template, null);
// attribution
TextView attributionViewSmall = nativeAdView
.findViewById(R.id.native_ad_attribution_small);
attributionViewSmall.setVisibility(View.VISIBLE);
// icon
nativeAdView.setIconView(nativeAdView.findViewById(R.id.native_ad_icon));
if (nativeAd.getIcon() == null) {
nativeAdView.getIconView().setVisibility(View.GONE);
} else {
((ImageView)nativeAdView.getIconView()).setImageDrawable(nativeAd.getIcon().getDrawable());
}
// media
MediaView mediaView = nativeAdView.findViewById(R.id.native_ad_media);
mediaView.setMediaContent(nativeAd.getMediaContent());
nativeAdView.setMediaView(mediaView);
// button
nativeAdView.setCallToActionView(nativeAdView.findViewById(R.id.native_ad_button));
if(nativeAd.getCallToAction()==null){
nativeAdView.getCallToActionView().setVisibility(View.INVISIBLE);
}else{
((Button)nativeAdView.getCallToActionView()).setText(nativeAd.getCallToAction());
}
// headline
nativeAdView.setHeadlineView(nativeAdView.findViewById(R.id.native_ad_headline));
((TextView)nativeAdView.getHeadlineView()).setText(nativeAd.getHeadline());
// bodyView
nativeAdView.setBodyView(nativeAdView.findViewById(R.id.native_ad_body));
if(nativeAd.getBody()==null){
nativeAdView.getBodyView().setVisibility(View.INVISIBLE);
}else {
((TextView)nativeAdView.getBodyView()).setText(nativeAd.getBody());
nativeAdView.getBodyView().setVisibility(View.VISIBLE);
}
// advertiser name
nativeAdView.setAdvertiserView(nativeAdView.findViewById(R.id.native_ad_advertiser));
if(nativeAd.getAdvertiser()==null){
nativeAdView.getAdvertiserView().setVisibility(View.GONE);
}else {
((TextView)nativeAdView.getAdvertiserView()).setText(nativeAd.getAdvertiser());
nativeAdView.getAdvertiserView().setVisibility(View.VISIBLE);
}
// ratingbar
nativeAdView.setStarRatingView(nativeAdView.findViewById(R.id.native_ad_rating));
if(nativeAd.getStarRating()==null){
nativeAdView.getStarRatingView().setVisibility(View.INVISIBLE);
}else{
((RatingBar)nativeAdView.getStarRatingView()).setRating(nativeAd.getStarRating().floatValue());
nativeAdView.getStarRatingView().setVisibility(View.VISIBLE);
}
nativeAdView.setNativeAd(nativeAd);
return nativeAdView;
}
}
Native ad small layout template.android/app/src/main/res/layout/small_template.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:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="75dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/native_ad_icon"
android:layout_width="60dp"
android:layout_height="60dp"
android:paddingRight="5dp"
android:scaleType="fitXY"
tools:background="#EDEDED" />
<LinearLayout
android:layout_width="200dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<RatingBar
android:id="@+id/native_ad_rating"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isIndicator="true"
android:numStars="5"
android:stepSize="0.5"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="0dp"
app:cardBackgroundColor="#00000000"
app:cardCornerRadius="2dp"
app:cardElevation="0dp">
<TextView
android:id="@+id/native_ad_attribution_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#F19938"
android:gravity="center"
android:padding="2dp"
android:text="Ad"
android:textColor="#FFFFFF"
android:textSize="10sp"
android:layout_marginRight="5dp"
/>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/native_ad_advertiser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:textColor="#828282"
android:textSize="12sp"
tools:text="advertiser name" />
</LinearLayout>
<TextView
android:id="@+id/native_ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:textColor="#000000"
android:textSize="16sp"
tools:text="Headline" />
</LinearLayout>
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="#1A73E8"
android:elevation="0dp"
android:gravity="center"
app:cardBackgroundColor="#1A73E8"
app:cardCornerRadius="8dp"
app:cardElevation="0dp"
android:layout_marginTop="5dp"
>
<Button
android:id="@+id/native_ad_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#1A73E8"
android:gravity="center"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:paddingRight="5dp"
android:paddingBottom="5dp"
android:textAllCaps="false"
android:textColor="#ffff"
android:textScaleX="0.9"
/>
</androidx.cardview.widget.CardView>
</LinearLayout>
<TextView
android:id="@+id/native_ad_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:textColor="#828282"
android:textSize="14sp"
tools:text="body" />
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
Native ad medium layout template.android/app/src/main/res/layout/medium_template.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:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/native_ad_media"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="5dp"
>
</com.google.android.gms.ads.nativead.MediaView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="75dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/native_ad_icon"
android:layout_width="65dp"
android:layout_height="65dp"
android:paddingRight="5dp"
android:scaleType="fitXY"
tools:background="#EDEDED" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RatingBar
android:id="@+id/native_ad_rating"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isIndicator="true"
android:numStars="5"
android:stepSize="0.5"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="5dp"
>
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="0dp"
app:cardBackgroundColor="#00000000"
app:cardCornerRadius="2dp"
app:cardElevation="0dp">
<TextView
android:id="@+id/native_ad_attribution_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#F19938"
android:gravity="center"
android:padding="2dp"
android:text="Ad"
android:textColor="#FFFFFF"
android:textSize="10sp"
android:layout_marginRight="5dp"
/>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/native_ad_advertiser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:textColor="#828282"
android:textSize="12sp"
tools:text="advertiser name" />
</LinearLayout>
<TextView
android:id="@+id/native_ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:textColor="#000000"
android:textSize="16sp"
tools:text="Headline" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/native_ad_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#828282"
android:textSize="14sp"
android:ellipsize="end"
android:lines="2"
android:maxLines="2"
android:layout_marginBottom="5dp"
tools:text="body" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="#1A73E8"
android:elevation="0dp"
android:gravity="center"
app:cardBackgroundColor="#1A73E8"
app:cardCornerRadius="8dp"
app:cardElevation="0dp"
>
<Button
android:id="@+id/native_ad_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#1A73E8"
android:gravity="center"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:paddingRight="5dp"
android:paddingBottom="5dp"
android:textAlignment="center"
android:textAllCaps="false"
android:textColor="#ffff"
tools:text="install now"
/>
</androidx.cardview.widget.CardView>
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
MainActivity for(Kotlin)
NativeAdFactory
should be registered to the GoogleMobileAdsPlugin
if your flutter app project using kotlin then use these code.android/app/src/main/kotlin/com/example/nativetemplates/MainActivity.kt
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin
class MainActivity : FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
// TODO: Register the ListTileNativeAdFactory
GoogleMobileAdsPlugin.registerNativeAdFactory(
flutterEngine, "listTileSmall",
NativeAdFactorySmall(context)
)
GoogleMobileAdsPlugin.registerNativeAdFactory(
flutterEngine, "listTileMedium",
NativeAdFactoryMedium(context)
)
}
override fun cleanUpFlutterEngine(flutterEngine: FlutterEngine) {
super.cleanUpFlutterEngine(flutterEngine)
// TODO: Unregister the ListTileNativeAdFactory
GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "listTile")
GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "listTileMedium")
}
}
MainActivity for(Java)NativeAdFactory
should be registered to the GoogleMobileAdsPlugin
if your flutter app project using java then use these code.android/app/src/main/java/com/example/nativetemplates/MainActivity.java
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) {
super.configureFlutterEngine(flutterEngine);
// TODO: Register the ListTileNativeAdFactory
GoogleMobileAdsPlugin.registerNativeAdFactory(flutterEngine, "listTile",
new NativeAdFactorySmall(getContext()));
GoogleMobileAdsPlugin.registerNativeAdFactory(flutterEngine, "listTileMedium",
new NativeAdFactoryMedium(getContext()));
}
@Override
public void cleanUpFlutterEngine(FlutterEngine flutterEngine) {
super.cleanUpFlutterEngine(flutterEngine);
// TODO: Unregister the ListTileNativeAdFactory
GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "listTile");
GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "listTileMedium");
}
}
Here is our main.dart file and our UI.lib/main.dartimport 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
MobileAds.instance.initialize();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late NativeAd _adSmall;
late NativeAd _adMedium;
bool _isAdLoaded = false;
bool _isAdLoadedMedium = false;
@override
void initState() {
super.initState();
_adSmall = NativeAd(
// Here in adUnitId: add your own ad unit ID before release build
adUnitId: NativeAd.testAdUnitId,
factoryId: 'listTileSmall',
request: const AdRequest(),
listener: NativeAdListener(
onAdLoaded: (_) {
setState(() {
_isAdLoaded = true;
});
},
onAdFailedToLoad: (ad, error) {
// Releases an ad resource when it fails to load
ad.dispose();
print('Ad load failed (code=${error.code} message=${error.message})');
},
),
);
_adSmall.load();
_adMedium = NativeAd(
// Here in adUnitId: add your own ad unit ID before release build
adUnitId: NativeAd.testAdUnitId,
factoryId: 'listTileMedium',
request: const AdRequest(),
listener: NativeAdListener(
onAdLoaded: (_) {
setState(() {
_isAdLoadedMedium = true;
});
},
onAdFailedToLoad: (ad, error) {
// Releases an ad resource when it fails to load
ad.dispose();
print('Ad load failed (code=${error.code} message=${error.message})');
},
),
);
_adMedium.load();
}
@override
void dispose() {
_adSmall.dispose();
_adMedium.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Column(
children: [
// small native ad template widget
_isAdLoaded
? Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
child: AdWidget(ad: _adSmall),
height: 150,
width: 400,
),
)
: const SizedBox.shrink(),
// medium native ad template widget
_isAdLoadedMedium
? Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
child: AdWidget(ad: _adMedium),
height: 380,
width: 400,
),
)
: const SizedBox.shrink(),
],
)),
);
}
}