Displaying Different Types of Advertisements (Banner, Interstitial, Rewarded) in Flutter

Mobile app monetization is a crucial aspect of app development, and advertisements are a primary source of revenue for many developers. Flutter, with its cross-platform capabilities, offers various ways to integrate different types of advertisements into your applications. This post will guide you through the process of displaying banner, interstitial, and rewarded ads in a Flutter app, using AdMob as the primary advertising network.

Introduction to Mobile Ads

Before diving into the code, it’s important to understand the types of ads commonly used in mobile apps:

  • Banner Ads: Small, rectangular ads displayed at the top or bottom of the screen. They are non-intrusive and constantly visible.
  • Interstitial Ads: Full-screen ads that cover the app interface. They are typically displayed at natural transition points in the app flow, like after completing a game level or opening a new screen.
  • Rewarded Ads: Ads that users can opt to watch in exchange for in-app rewards. These are popular for their non-intrusive nature and user engagement.

Prerequisites

Before starting, ensure you have the following set up:

  • Flutter SDK: Installed and configured.
  • Firebase Project: Created and linked to your Flutter app, as AdMob is integrated with Firebase.
  • AdMob Account: Created and ad units (banner, interstitial, rewarded) set up. Note their respective ad unit IDs.

Step 1: Add Required Dependencies

Add the google_mobile_ads package to your pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  google_mobile_ads: ^4.0.0 # Use the latest version

Run flutter pub get to install the dependencies.

Step 2: Initialize Mobile Ads

In your main.dart file, initialize the Mobile Ads SDK:

import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter AdMob Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'AdMob Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () {
                _showInterstitialAd();
              },
              child: Text('Show Interstitial Ad'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                _showRewardedAd();
              },
              child: Text('Show Rewarded Ad'),
            ),
            SizedBox(height: 20),
            // Banner Ad Widget will be added here
            Container(
              child: AdBanner(),
            )
          ],
        ),
      ),
    );
  }

  // Implement Interstitial Ad methods here
  void _showInterstitialAd() {}

  // Implement Rewarded Ad methods here
  void _showRewardedAd() {}
}

Step 3: Implementing Banner Ads

Create a widget for displaying banner ads:

import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'dart:io';

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

  @override
  State<AdBanner> createState() => _AdBannerState();
}

class _AdBannerState extends State<AdBanner> {
  late BannerAd _bannerAd;
  bool _isAdLoaded = false;

  String get bannerAdUnitId {
    if (Platform.isIOS) {
      return 'YOUR_IOS_BANNER_AD_UNIT_ID'; // Replace with your iOS banner ad unit ID
    } else if (Platform.isAndroid) {
      return 'YOUR_ANDROID_BANNER_AD_UNIT_ID'; // Replace with your Android banner ad unit ID
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

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

  _initBannerAd() async {
    _bannerAd = BannerAd(
      adUnitId: bannerAdUnitId,
      request: AdRequest(),
      size: AdSize.banner,
      listener: BannerAdListener(
        // Called when an ad is successfully received.
        onAdLoaded: (Ad ad) {
          setState(() {
            _isAdLoaded = true;
          });
          print('$ad loaded.');
        },
        // Called when an ad request failed.
        onAdFailedToLoad: (Ad ad, LoadAdError error) {
          // Dispose the ad here to free resources.
          ad.dispose();
          print('Ad failed to load: ${error.message}');
        },
        // Called when an ad opens an overlay that covers the screen.
        onAdOpened: (Ad ad) => print('$ad opened.'),
        // Called when an ad removes an overlay that covers the screen.
        onAdClosed: (Ad ad) => print('$ad closed.'),
        // Called when an ad is in the process of leaving the application.
        onAdWillLeaveApplication: (Ad ad) => print('left application.'),
      ),
    );
    _bannerAd.load();
  }

  @override
  void dispose() {
    _bannerAd.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: _bannerAd.size.width.toDouble(),
      height: _bannerAd.size.height.toDouble(),
      child: _isAdLoaded ? AdWidget(ad: _bannerAd) : null,
    );
  }
}

Remember to replace YOUR_IOS_BANNER_AD_UNIT_ID and YOUR_ANDROID_BANNER_AD_UNIT_ID with your actual AdMob ad unit IDs.

Step 4: Implementing Interstitial Ads

Implement the interstitial ad functionality:


import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'dart:io';

// ... (Inside _MyHomePageState class)

InterstitialAd? _interstitialAd;
bool _isInterstitialAdReady = false;

String get interstitialAdUnitId {
    if (Platform.isIOS) {
      return 'YOUR_IOS_INTERSTITIAL_AD_UNIT_ID'; // Replace with your iOS interstitial ad unit ID
    } else if (Platform.isAndroid) {
      return 'YOUR_ANDROID_INTERSTITIAL_AD_UNIT_ID'; // Replace with your Android interstitial ad unit ID
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }


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

void _loadInterstitialAd() {
  InterstitialAd.load(
    adUnitId: interstitialAdUnitId,
    request: AdRequest(),
    adLoadCallback: InterstitialAdLoadCallback(
      onAdLoaded: (InterstitialAd ad) {
        _interstitialAd = ad;
        _isInterstitialAdReady = true;
        print('$ad loaded.');
        _interstitialAd?.fullScreenContentCallback = FullScreenContentCallback(
            onAdShowedFullScreenContent: (InterstitialAd ad) =>
                print('$ad onAdShowedFullScreenContent.'),
            onAdDismissedFullScreenContent: (InterstitialAd ad) {
              print('$ad onAdDismissedFullScreenContent.');
              ad.dispose();
              _loadInterstitialAd();
            },
            onAdFailedToShowFullScreenContent: (InterstitialAd ad, AdError error) {
              print('$ad onAdFailedToShowFullScreenContent: $error');
              ad.dispose();
              _loadInterstitialAd();
            });
      },
      onAdFailedToLoad: (LoadAdError error) {
        print('InterstitialAd failed to load: $error');
      },
    ),
  );
}

void _showInterstitialAd() {
  if (_isInterstitialAdReady) {
    _interstitialAd!.show();
  } else {
    print('Interstitial Ad not ready yet!');
  }
}

@override
void dispose() {
    _interstitialAd?.dispose();
    super.dispose();
  }

Make sure to replace YOUR_IOS_INTERSTITIAL_AD_UNIT_ID and YOUR_ANDROID_INTERSTITIAL_AD_UNIT_ID with your AdMob interstitial ad unit IDs.

Step 5: Implementing Rewarded Ads

Implement the rewarded ad functionality:

import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'dart:io';

// ... (Inside _MyHomePageState class)

RewardedAd? _rewardedAd;
bool _isRewardedAdReady = false;

String get rewardedAdUnitId {
    if (Platform.isIOS) {
      return 'YOUR_IOS_REWARDED_AD_UNIT_ID'; // Replace with your iOS rewarded ad unit ID
    } else if (Platform.isAndroid) {
      return 'YOUR_ANDROID_REWARDED_AD_UNIT_ID'; // Replace with your Android rewarded ad unit ID
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

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


void _loadRewardedAd() {
  RewardedAd.load(
    adUnitId: rewardedAdUnitId,
    request: AdRequest(),
    rewardedAdLoadCallback: RewardedAdLoadCallback(
      onAdLoaded: (RewardedAd ad) {
        _rewardedAd = ad;
        _isRewardedAdReady = true;
        print('$ad loaded.');
        _rewardedAd!.fullScreenContentCallback = FullScreenContentCallback(
          onAdShowedFullScreenContent: (RewardedAd ad) =>
              print('$ad onAdShowedFullScreenContent.'),
          onAdDismissedFullScreenContent: (RewardedAd ad) {
            print('$ad onAdDismissedFullScreenContent.');
            ad.dispose();
            _loadRewardedAd();
          },
          onAdFailedToShowFullScreenContent: (RewardedAd ad, AdError error) {
            print('$ad onAdFailedToShowFullScreenContent: $error');
            ad.dispose();
            _loadRewardedAd();
          },
        );
      },
      onAdFailedToLoad: (LoadAdError error) {
        print('RewardedAd failed to load: $error');
      },
    ),
  );
}

void _showRewardedAd() {
  if (_isRewardedAdReady) {
    _rewardedAd!.show(
        onUserEarnedReward: (AdWithoutView ad, RewardItem reward) {
      print(
          '$ad with reward ${reward.amount} ${reward.type}');
    });
  } else {
    print('Rewarded Ad not ready yet!');
  }
}

@override
void dispose() {
    _rewardedAd?.dispose();
    super.dispose();
  }

Be sure to replace YOUR_IOS_REWARDED_AD_UNIT_ID and YOUR_ANDROID_REWARDED_AD_UNIT_ID with your appropriate ad unit IDs. Also remember to implement your reward logic inside the `onUserEarnedReward` callback.

Handling AdMob IDs

It is crucial to handle AdMob ad unit IDs properly, particularly when building for different platforms (iOS and Android). Using conditional checks based on the platform can ensure the correct ID is used at runtime:


import 'dart:io';

String getAdUnitId() {
  if (Platform.isIOS) {
    return 'YOUR_IOS_ADMOB_ID';
  } else if (Platform.isAndroid) {
    return 'YOUR_ANDROID_ADMOB_ID';
  } else {
    throw new UnsupportedError('Unsupported platform');
  }
}

Conclusion

Integrating different types of advertisements (banner, interstitial, and rewarded) in a Flutter app involves adding the google_mobile_ads dependency, initializing the Mobile Ads SDK, and implementing each ad format using their respective classes. By using platform-specific ad unit IDs and handling ad states appropriately, you can effectively monetize your Flutter application while providing a seamless user experience. Always remember to test ads thoroughly and adhere to AdMob’s policies to avoid any violations.