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.dart
import '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(),
],
)),
);
}
}


Popular posts from this blog

In-App Purchase with null safety in Flutter 2.5.

How to add In-App Purchase subscription in Flutter.