With lack of official document support for adding google native ads in flutter, it is hard for some developers to get this thing done. Google also provide banner ad with bigger size that looks like native ad but it can not replace original native ad as they both are having major differences mainly in revenue department. Native Ads having higher ecpm than Banner ads can be more useful for developers.
In this article we are going to see how we can easily integrate google native ads in flutter.
Â
So Firstly, Let’s get our setup for showing google ads in flutter done.
Â
1. Setup App to show Google Ads
1. Run below command with flutter to add google_mobile_ads in you project:
$ flutter pub add google_mobile_ads
OR
1. Add following under dependencies in your project’s pubspec.yaml file.
dependencies:
  google_mobile_ads : ^1.0.0
Official Package :Â google_mobile_ads | Flutter Package (pub.dev)
Now, run flutter pub get
2. Let’s make some changes in our app level build.gradle file
compileSdkVersion 31
  defaultConfig {
     applicationId “com.example.googleAds”
    minSdkVersion 19
    targetSdkVersion 31
    multiDexEnabled true
    versionCode flutterVersionCode.toInteger()
    versionName flutterVersionName
  }
Make sure that you have compileSdkVersion 28 or higher and minSdkVersion 19 or higher.
Â
3. Add AdMob ID in AndroidMenifest file.
<manifest>
  <application>
    <!– Sample AdMob app ID: ca-app-pub-3940256099942544~3347511713 –>
    <meta-data
      android:name=”com.google.android.gms.ads.APPLICATION_ID”
      android:value=”ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy”/>
  <application>
<manifest>
4. Add following lines to your main.dart file
void main() {
 WidgetsFlutterBinding.ensureInitialized();
 MobileAds.instance.initialize();
 runApp(MyApp());
}
Now Almost all setup is Done. It’s time to use this in our code to show Ads.
2. Show Google Native Ads
2.1 Setup XML Layouts to shape our Native Ad Layout.
Go to
 your_project_root → android → app → src → main → res → layout

if you don’t have layout folder then create one under res.
We have to add this two files in that layout folder.
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="160dp"
android:orientation="vertical">
<TextView
android:id="@+id/native_ad_attribution_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:background="#F19938"
android:gravity="center"
android:padding="2dp"
android:text="Ad"
android:textColor="#FFFFFF"
android:textSize="10sp"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/native_ad_icon"
android:layout_width="55dp"
android:layout_height="55dp"
android:paddingRight="5dp"
android:scaleType="fitXY"
tools:background="#EDEDED" />
<LinearLayout
android:layout_width="200dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/native_ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:textColor="#000000"
android:textSize="16dp"
tools:text="Headline" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:orientation="horizontal">
<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="12dp"
tools:text="advertiser name" />
</LinearLayout>
</LinearLayout>
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<RatingBar
android:id="@+id/native_ad_rating"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:isIndicator="true"
android:numStars="5"
android:stepSize="0.5" />
</LinearLayout>
<TextView
android:id="@+id/native_ad_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:ellipsize="end"
android:lines="2"
android:maxLines="2"
android:textColor="#828282"
android:textSize="12dp"
tools:text="body" />
<Button
android:id="@+id/native_ad_button"
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="#0070BA"
android:text="Install"
android:textAllCaps="true"
android:textColor="#ffff"
android:textScaleX="0.9"
/>
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
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">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/native_ad_attribution_small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:background="#F19938"
android:gravity="center"
android:padding="2dp"
android:text="Ad"
android:textColor="#FFFFFF"
android:textSize="10sp"
/>
<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="120dp"
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="60dp"
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="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RatingBar
android:layout_marginLeft="2dp"
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:layout_margin="2dp"
android:orientation="horizontal">
<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:layout_marginLeft="2dp"
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:layout_marginBottom="5dp"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:textColor="#828282"
android:textSize="14sp"
tools:text="body" />
<Button
android:id="@+id/native_ad_button"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#0070BA"
android:text="Install"
android:textAllCaps="true"
android:textColor="#ffff"
android:textScaleX="0.9"
/>
</LinearLayout>
</FrameLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
Now Your layout folder should look like this:Â

Now, Go to
 your_project_root → android → app → src → main → java → com.xyz.abcÂ

Add Following files in that com.xyz.abc folder and make some tweeks in MainActivity.java file
MainAcitivty.java
package com.example.dl_online_v2;
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.android.FlutterActivity;
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");
}
}
NativeAdFactorySmall.java
package com.example.dl_online_v2;
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;
}
}
NativeAdFactoryMedium.java
package com.example.dl_online_v2;
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;
}
}
We are done with out setup for native ad. It’s Time to show Native ad.
2.2 Show Native Ad
NativeAd? nativeAd;
bool isNativeAdLoaded = false;
@override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
loadNativeAd();
}
void loadNativeAd() {
nativeAd = NativeAd(
adUnitId: AdManager.nativeAdID,
factoryId: wantSmallNativeAd ? "listTile" : "listTileMedium",
listener: NativeAdListener(onAdLoaded: (ad) {
setState(() {
isNativeAdLoaded = true;
});
}, onAdFailedToLoad: (ad, error) {
loadNativeAd2();
nativeAd!.dispose();
}),
request: const AdRequest(),
);
nativeAd!.load();
}
in build method add following code to show native ad:
isNativeAdLoaded
? Container(
decoration: const BoxDecoration(
color: Colors.white,
),
height: doYouWantSmallNativeAd ? 140 : 265,
child: AdWidget(
ad: nativeAd!,
),
)
: SizedBox();
hope You are clear with this. if you have any queries then feel free to ask in comment section Thank you. keep Supporting and Happy Coding. 🙂
Thankz!!