How to integrate Google AdMob Native Ads in Flutter

Flutter June 22nd 2022

    Create a blank flutter project:

    flutter create native_ads_flutter

    Add provider package: 

    flutter pub add google_mobile_ads

    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 19" and "multiDexEnabled true"

    android/app/build.gradle
    defaultConfig {
    // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
    applicationId "com.example.native_ads_flutter"
    minSdkVersion 19
    multiDexEnabled true
    targetSdkVersion flutter.targetSdkVersion
    versionCode flutterVersionCode.toInteger()
    versionName flutterVersionName
    }
    Native ad layout template.
    android/app/src/main/res/layout/list_tile_native_ad.xml
    Input:

    <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" />





    ListTileNativeAdFactory class for list_tile_native_ad template.
    android/app/src/main/kotlin/com/example/native_ads_flutter/ListTileNativeAdFactory.kt
    Input:
    package com.example.native_ads_flutter

    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(R.id.tv_list_tile_native_ad_attribution_small)
    val attributionViewLarge =
    findViewById(R.id.tv_list_tile_native_ad_attribution_large)

    val iconView = findViewById(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(R.id.tv_list_tile_native_ad_headline)
    headlineView.text = nativeAd.headline
    this.headlineView = headlineView

    val bodyView = findViewById(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
    }
    }

    MainActivity for(Kotlin)

    ListTileNativeAdFactory should be registered to the GoogleMobileAdsPlugin
    if your flutter app project using kotlin then use these code.
    android/app/src/main/kotlin/com/example/native_ads_flutter/MainActivity.kt
    Input:
    package com.example.native_ads_flutter

    import io.flutter.embedding.android.FlutterActivity
    import io.flutter.embedding.engine.FlutterEngine
    import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin

    //This is the final version of kotlin main activity
    class MainActivity: FlutterActivity() {

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)

    GoogleMobileAdsPlugin.registerNativeAdFactory(
    flutterEngine, "listTile", ListTileNativeAdFactory(context))
    }

    override fun cleanUpFlutterEngine(flutterEngine: FlutterEngine) {
    super.cleanUpFlutterEngine(flutterEngine)
    GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "listTile")
    }

    }

    Here is our main.dart file and our UI.
    lib/main.dart
    Input:
    import 'package:flutter/material.dart';
    import 'package:google_mobile_ads/google_mobile_ads.dart';

    void main() {
    WidgetsFlutterBinding.ensureInitialized();
    MobileAds.instance.initialize();
    runApp(const MaterialApp(
    home: NativeAdExample(),
    ));
    }


    ///An App to demonstrate how to use admob native ads in flutter
    ///make sure to change the value of APPLICATION_ID in android manifest
    ///make sure to use a real ad unit id from admob and change it below

    class NativeAdExample extends StatefulWidget {
    const NativeAdExample({Key? key}) : super(key: key);

    @override
    _NativeAdExampleState createState() => _NativeAdExampleState();
    }

    class _NativeAdExampleState extends State {

    late NativeAd _ad;
    bool isLoaded = false;

    @override
    void initState() {
    super.initState();
    loadNativeAd();
    }

    ///Important make sure to dispose the ad when disposing the screen
    @override
    void dispose() {
    _ad.dispose();
    super.dispose();
    }


    void loadNativeAd() {
    _ad = NativeAd(
    request: const AdRequest(),
    ///This is a test adUnitId make sure to change it
    adUnitId: 'ca-app-pub-3940256099942544/2247696110',
    factoryId: 'listTile',
    listener: NativeAdListener(
    onAdLoaded: (ad){
    setState(() {
    isLoaded = true;
    });
    },
    onAdFailedToLoad: (ad, error){
    ad.dispose();
    print('failed to load the ad ${error.message}, ${error.code}');
    }
    )
    );

    _ad.load();
    }

    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
    title: const Text('Flutter Native Ad'),
    centerTitle: true,
    ),
    body: Padding(
    padding: const EdgeInsets.all(12.0),
    child: ListView.builder(
    itemCount: 5,
    itemBuilder: (context, index){
    if(isLoaded && index == 2){
    return Container(
    child: AdWidget(ad: _ad,),
    alignment: Alignment.center,
    height: 170,
    color: Colors.black12,
    );
    }else{
    return ListTile(
    title: Text('Item ${index + 1}'),
    leading: const FlutterLogo(size: 25,),
    subtitle: Text('Sub Title for item ${index + 1}'),
    );
    }

    }
    ),
    ),
    );
    }
    }

    You can find my GitHub code here:

    https://github.com/rogerphan0623/native_ads_flutter