Adding AdMob ads to a Flutter app

What you'll build

This codelab guides you through adding an AdMob banner, an interstitial ad, and a rewarded ad to an app called Awesome Drawing Quiz, a game that lets players guess the name of the drawing.

If you run into any issues (code bugs, grammatical errors, unclear wording) as you work through this codelab, please report the issue by clicking the Report a mistake link in the lower, left corner of the codelab.

What you'll learn

  • How to set up a Firebase project for a Flutter app
  • How to configure the Firebase AdMob plugin
  • How to use banner, interstitial, and rewarded ads in a Flutter app

What you'll need

  • Android Studio 3.6 or higher
  • Xcode (for iOS support)

How would you rate your level of experience with AdMob?

Novice Intermediate Proficient

What would you like to learn from this codelab?

I'm new to the topic, and I want a good overview. I know something about this topic, but I want a refresher. I'm looking for example code to use in my project. I'm looking for an explanation of something specific.

Set up the Flutter development environment

  1. Install the Flutter SDK on your machine by following the installation instructions on flutter.dev.
  2. Open Android Studio, and follow the steps on the configuration page to install the Flutter and Dart plugins for Android Studio.

Download the code

To download all the code for this codelab as a zip file, click the following button:

Download source code

Extract the files from the zip file. This unpacks a root folder named admob-ads-in-flutter-master.

Or, clone the GitHub repository from the command line.

$ git clone https://github.com/googlecodelabs/admob-ads-in-flutter

The repository contains two folders:

  • android_studio_folder.pngstarter — Starting code that you use to build this codelab.
  • android_studio_folder.pngcomplete — Completed code for this codelab.

Import the starter project

  1. Open Android Studio.
  2. From the welcome screen, select Open an existing Android Studio project. a3a1fa1afc967e37.png
  3. Open the android_studio_folder.pngstarter folder from the code you downloaded in the previous step.

a879fa2385ba368f.png

  1. You may see the following error messages from the Dart Analysis tab. This error happens only once when you imported the existing project to Android Studio because the packages being used in the sample project are not downloaded yet.

2b8fbccf84e1e8a5.png

  1. To fix the error, click Get dependencies at the top of the editor pane. It will download the packages that the sample project depends on.

dc017166e44ac333.png

  1. Once the download is complete, you should see no errors from the Dart Analysis tab. Now your project is ready for development.

You need to set up a Firebase project to serve AdMob ads with the Firebase AdMob Plugin.

Create a Firebase project

  1. In the Firebase console, click Add project.
  2. Enter Awesome Drawing Quiz as the project name.
  3. Enable Google Analytics for your project and click Continue.

87590d75b00db648.png

  1. Choose the analytics location and settings that apply to your project. Read and accept the terms, and then click Create project.

700c64d82fedbd0b.png

  1. After a minute or so, your Firebase project is ready.

Register the app with Firebase

In the Firebase console, select the Awesome Drawing Quiz project that you created in the previous step.

Register an Android app

  1. In the center of the project overview page, click the Android icon to launch the setup workflow.
  2. Enter com.codelab.awesomedrawingquiz in the Android package name field.
  3. Enter Awesome Drawing Quiz (Android) in the App nickname field.
  4. Click Register app.
  5. Download the google-services.json file for future use.

Register an iOS app

  1. In the center of the project overview page, click the iOS icon or Add app (+) icon to launch the setup workflow.
  2. Enter com.codelab.awesomedrawingquiz in the iOS bundle ID field.
  3. Enter Awesome Drawing Quiz (iOS) in the App nickname field.
  4. Click Register app.
  5. Download the GoogleService-Info.plist file for future use.

Add a Firebase configuration file

The following instructions tell you how to configure Firebase for both Android and iOS.

Configure for Android

  1. Open the starter project in Android Studio by referring Import the starter project section in Set up the development environment step in this codelab.
  2. Move the google-services.json file into the android/app directory of the Awesome Drawing Quiz Flutter project.

bd0729c424b0c79d.png

  1. In the root-level (project-level) Gradle file (android/build.gradle), add rules to include the Google Services Gradle plugin. Check that you have Google's Maven repository.

android/build.gradle

buildscript {

    repositories {
      // Check that you have the following line (if not, add it):
      google()  // Google's Maven repository
    }

    ...

    dependencies {
      ...

      // TODO: Add Google Services plugin
      classpath 'com.google.gms:google-services:4.3.3'
    }
}

allprojects {
    ...

    repositories {
      // Check that you have the following line (if not, add it):
      google()  // Google's Maven repository
      ...
    }
}
  1. In the module (app-level) Gradle file (android/app/build.gradle), apply the Google Services Gradle plugin.

android/app/build.gradle

...

// TODO: Apply google-services plugin
apply plugin: 'com.google.gms.google-services'

android {
  ...
}

...

Configure for iOS

  1. Open the starter project in Android Studio by referring Import the starter project section in Set up the development environment step in this codelab.
  2. Open any file under the ios directory. (for example, ios/Runner/AppDelegate.swift)
  3. Click Open iOS module in Xcode.

b0e50d31ada7bf46.png

  1. In Xcode, drag the GoogleService-Info.plist file into the Runner directory, to import the configuration file into the Xcode project.

1f552ff12b67008.png

Because Flutter is a multi-platform SDK, you need to add an app and ad units for both Android and iOS in AdMob.

Before you start, you want to be familiar with the following AdMob glossaries.

Ad unit

Ad unit is a set of ads displayed as a result of one piece of the AdMob ad code. You can create and customize an ad unit in your AdMob account.

Each ad unit has a unique identifier, called the ad unit ID. When you implement a new ad unit in your app, you'll reference the ad unit ID to tell ad networks where to send ads when requested.

Banner ad

Banner ads occupy a spot within an app's layout, either at the top or bottom of the device screen. They stay on screen while users are interacting with the app, and can refresh automatically after a certain period of time.

Interstitial ad

Interstitial ads are full-screen ads that cover the interface of their host app. They're typically displayed at natural transition points in the flow of an app, such as between activities or during the pause between levels in a game.

Rewarded ad

Rewarded ads are ads that users have the option of interacting with in exchange for in-app rewards.

Set up for Android

This section tells you how to add an Android app, and ad units, to AdMob.

Add an Android app

Use the following instructions to add an Android app to AdMob:

  1. In the AdMob console, click ADD APP from the Apps menu.
  2. When you're asked ‘Have you published your app on Google Play or the App Store?', click NO.
  3. Enter Awesome Drawing Quiz in the App name field, and select Android as the platform.

152e1694fd0ce870.png

  1. Enabling user metrics is not mandatory to complete this codelab. However, it's recommended because enabling user metrics provides the analytics data with detailed user behavior. Click ADD to complete the process.

5204925f5c652b41.png

  1. Make a note of your new app ID (ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy). You'll need to add it to the sample project's source code to run ads.

Create ad units

To start adding ad units to AdMob:

  1. Select Awesome Drawing Quiz (Android) from the Apps menu in the AdMob console.
  2. Click the Ad units menu.

From the Ad units menu, follow the instructions to create a banner, an interstitial ad, and a rewarded ad unit.

Banner

  1. Click the ADD AD UNIT button.
  2. Select Banner as the format.
  3. Enter android-adq-banner in the Ad unit name field.
  4. Click CREATE AD UNIT to complete the process.

Interstitial

  1. Click the ADD AD UNIT button.
  2. Select Interstitial as the format.
  3. Enter android-adq-interstitial in the Ad unit name field.
  4. Click CREATE AD UNIT to complete the process.

Rewarded

  1. Click the ADD AD UNIT button.
  2. Select Rewarded as the format.
  3. Enter android-adq-rewarded in the Ad unit name field.
  4. Leave the default for Reward settings.
  5. Click CREATE AD UNIT to complete the process.

Set up for iOS

This section tells you how to add an iOS app, and ad units, to AdMob.

Add an iOS app

Use the following instructions to add an iOS app to AdMob:

  1. In the AdMob console, click ADD APP from the Apps menu.
  2. When you're asked ‘Have you published your app on Google Play or the App Store?', click NO.
  3. Enter Awesome Drawing Quiz in the App name field, and select iOS as the platform.

a8fa48af652021d8.png

  1. Enabling user metrics is not mandatory to complete this codelab. However, it's recommended because enabling user metrics provides the analytics data with detailed user behavior. Click ADD to complete the process.

5204925f5c652b41.png

  1. Make a note of your new app ID (ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy). You'll need to add it to the sample project's source code to run ads.

Create ad units

To start adding ad units:

  1. Select Awesome Drawing Quiz (iOS) from the Apps menu in the AdMob console.
  2. Click the Ad units menu.

From the Ad units menu, follow the instructions to create a banner, an interstitial ad, and a rewarded ad unit.

Banner

  1. Click the ADD AD UNIT button.
  2. Select Banner as the format.
  3. Enter ios-adq-banner in the Ad unit name field.
  4. Click CREATE AD UNIT to complete the process.

Interstitial

  1. Click the ADD AD UNIT button.
  2. Select Interstitial as the format.
  3. Enter ios-adq-interstitial in the Ad unit name field.
  4. Click CREATE AD UNIT to complete the process.

Rewarded

  1. Click the ADD AD UNIT button.
  2. Select Rewarded as the format.
  3. Enter ios-adq-rewarded in the Ad unit name field.
  4. Leave the default for Reward settings.
  5. Click CREATE AD UNIT to complete the process.

Use the preconfigured AdMob app and ad units (optional)

If you want to follow the codelab instead of creating a new application and ad units by yourself, you can use the following AdMob app ID and ad unit IDs prepared for this codelab instead.

Android

Test AdMob IDs for Android:

Item

app ID/ad unit ID

AdMob app ID

ca-app-pub-3940256099942544~4354546703

Banner

ca-app-pub-3940256099942544/8865242552

Interstitial

ca-app-pub-3940256099942544/7049598008

Rewarded

ca-app-pub-3940256099942544/8673189370

iOS

Test AdMob IDs for iOS:

Item

app ID/ad unit ID

AdMob app ID

ca-app-pub-3940256099942544~2594085930

Banner

ca-app-pub-3940256099942544/4339318960

Interstitial

ca-app-pub-3940256099942544/3964253750

Rewarded

ca-app-pub-3940256099942544/7552160883

Flutter uses plugins to provide access to a wide range of platform-specific services. Plugins include platform-specific code to access services and APIs on each platform.

The firebase_admob plugin supports loading and displaying banner, interstitial, and rewarded ads by using the AdMob API.

Because Flutter is a multi-platform SDK, the firebase_admob plugin is applicable for both iOS and Android. So, if you add the plugin to your Flutter app, it is used by both the Android and iOS versions of the Awesome Drawing Quiz app.

Adding the Firebase AdMob plugin as a dependency

To access the AdMob APIs from the Awesome Drawing Quiz project, add the firebase_admob plugin as a dependency to the pubspec.yaml file located at the root of the project.

pubspec.yaml

...

dependencies:
  flutter:
    sdk: flutter
  google_fonts: ^0.3.9

  # Add the following line
  firebase_admob: ^0.9.3

...

Click Packages get to install the plugin into the Awesome Drawing Quiz project.

d9fc62bf4054cea9.png

Update AndroidManifest.xml (Android)

  1. Open the android/app/src/main/AndroidManifest.xml file in Android Studio.
  2. Add your AdMob app ID by adding a <meta-data> tag and entering com.google.android.gms.ads.APPLICATION_ID. If your AdMob app ID is ca-app-pub-3940256099942544~3347511713, then you need to add the following lines to the AndroidManifest.xml file.

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>

Update Info.plist (iOS)

  1. Open the ios/Runner/Info.plist file in Android Studio.
  2. Add a GADApplicationIdentifier key with the string value of your AdMob app ID. For example, if your AdMob app ID is ca-app-pub-3940256099942544~1458002511, then you need to add the following lines to the Info.plist file.

ios/Runner/Info.plist

...
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-3940256099942544~1458002511</string>
...

Create a new file named ad_manager.dart under the lib directory. Then, implement the AdManager class which provides an AdMob app ID and ad unit IDs for Android and iOS.

Make sure that you replace the AdMob app ID (ca-app-pub-xxxxxx~yyyyy) and the ad unit ID (ca-app-pub-xxxxxxx/yyyyyyyy) with the IDs you created in the previous step.

lib/ad_manager.dart

import 'dart:io';

class AdManager {

  static String get appId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_ADMOB_APP_ID>";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_ADMOB_APP_ID>";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get bannerAdUnitId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_BANNER_AD_UNIT_ID";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_BANNER_AD_UNIT_ID>";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get interstitialAdUnitId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_INTERSTITIAL_AD_UNIT_ID>";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_INTERSTITIAL_AD_UNIT_ID>";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get rewardedAdUnitId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_REWARDED_AD_UNIT_ID>";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_REWARDED_AD_UNIT_ID>";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }
}

Use the following code snippet if you want to use the preconfigured AdMob app ID and ad unit IDs for this codelab.

lib/ad_manager.dart

import 'dart:io';

class AdManager {

  static String get appId {
    if (Platform.isAndroid) {
      return "ca-app-pub-3940256099942544~4354546703";
    } else if (Platform.isIOS) {
      return "ca-app-pub-3940256099942544~2594085930";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get bannerAdUnitId {
    if (Platform.isAndroid) {
      return "ca-app-pub-3940256099942544/8865242552";
    } else if (Platform.isIOS) {
      return "ca-app-pub-3940256099942544/4339318960";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get interstitialAdUnitId {
    if (Platform.isAndroid) {
      return "ca-app-pub-3940256099942544/7049598008";
    } else if (Platform.isIOS) {
      return "ca-app-pub-3940256099942544/3964253750";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }

  static String get rewardedAdUnitId {
    if (Platform.isAndroid) {
      return "ca-app-pub-3940256099942544/8673189370";
    } else if (Platform.isIOS) {
      return "ca-app-pub-3940256099942544/7552160883";
    } else {
      throw new UnsupportedError("Unsupported platform");
    }
  }
}

Before loading ads, you need to initialize the AdMob SDK. Open the lib/home_route.dart file, and modify _initAdMob() to initialize the SDK before the game starts.

lib/home_route.dart

// TODO: Import ad_manager.dart
import 'package:awesome_drawing_quiz/ad_manager.dart';

import 'package:awesome_drawing_quiz/app_theme.dart';

// TODO: Import firebase_admob.dart
import 'package:firebase_admob/firebase_admob.dart';

import 'package:flutter/material.dart';

...

class _HomeRouteState extends State<HomeRoute> {

  ...

  Future<void> _initAdMob() {
    // TODO: Initialize AdMob SDK
    return FirebaseAdMob.instance.initialize(appId: AdManager.appId);
  }
}

In this section, you add a banner ad at the top of the game screen, as shown.

580a296a77065928.png 6d6659121dbf382e.png

Open the lib/game_route.dart file, and import ad_manager.dart and firebase_admob.dart by adding the following lines:

lib/game_route.dart

...

// TODO: Import ad_manager.dart
import 'package:awesome_drawing_quiz/ad_manager.dart';

// TODO: Import firebase_admob.dart
import 'package:firebase_admob/firebase_admob.dart';

class GameRoute extends StatefulWidget {
  ...
}

Next, in the _GameRouteState class, add the following member and methods for the banner ad.

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {
  
  ...

  // TODO: Add _bannerAd
  BannerAd _bannerAd;

  ...

  // TODO: Implement _loadBannerAd()
  void _loadBannerAd() {
    _bannerAd
      ..load()
      ..show(anchorType: AnchorType.top);
  }

  ...
}

In the initState() method, create a BannerAd object, and load the banner ad. Note that the banner displays a 320x50 banner (AdSize.banner).

lib/game_route.dart

@override
void initState() {
  ...
 
  // TODO: Initialize _bannerAd
  _bannerAd = BannerAd(
      adUnitId: AdManager.bannerAdUnitId,
      size: AdSize.banner,
  );

  // TODO: Load a Banner Ad
  _loadBannerAd();
}

Finally, release the resource associated with the BannerAd object by calling the BannerAd.dispose() method in the dispose() callback method.

lib/game_route.dart

@override
void dispose() {
  // TODO: Dispose BannerAd object
  _bannerAd?.dispose();

  ...

  super.dispose();
}

That's it! Run the project, to see a banner ad shown at the top of the game screen.

d82f07411be93d37.png f221e4821191cf99.png

In this section, you display an interstitial ad after the game (5 levels in total) finishes.

First, add the following members and methods for the interstitial ad in the _GameRouteState class.

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {
  
  ...

  // TODO: Add _interstitialAd
  InterstitialAd _interstitialAd;

  // TODO: Add _isInterstitialAdReady
  bool _isInterstitialAdReady;

  ...

  // TODO: Implement _loadInterstitialAd()
  void _loadInterstitialAd() {
    _interstitialAd.load();
  }

  // TODO: Implement _onInterstitialAdEvent()
  void _onInterstitialAdEvent(MobileAdEvent event) {
    switch (event) {
      case MobileAdEvent.loaded:
        _isInterstitialAdReady = true;
        break;
      case MobileAdEvent.failedToLoad:
        _isInterstitialAdReady = false;
        print('Failed to load an interstitial ad');
        break;
      case MobileAdEvent.closed:
        _moveToHome();
        break;
      default:
      // do nothing
    }
  }

  ...
}

Next, initialize _isInterstitialAdReady and _interstitialAd in the initState() method. Because _onInterstitialAdEvent is configured as an ad event listener for _interstitialAd, every ad event from _interstitialAd is delivered to the _onInterstitialAdEvent method.

lib/game_route.dart

@override
void initState() {
  ...

  // TODO: Initialize _isInterstitialAdReady
  _isInterstitialAdReady = false;
 
  // TODO: Initialize _interstitialAd
  _interstitialAd = InterstitialAd(
    adUnitId: AdManager.interstitialAdUnitId,
    listener: _onInterstitialAdEvent,
  );
}

In this codelab, an interstitial ad is displayed after a user completes 5 levels. To minimize unnecessary ad requests, we start loading an ad when a user reaches level 3.

In the onNewLevel() method, add the following lines.

lib/game_route.dart

@override
void onNewLevel(int level, Drawing drawing, String clue) {
  ...

  // TODO: Load an Interstitial Ad
  if (level >= 3 && !_isInterstitialAdReady) {
    _loadInterstitialAd();
  }
}

When a game finishes, the game score dialog is displayed. When a user closes the dialog, it routes a user to the home screen of the Awesome Drawing Quiz.

Because interstitial ads should be displayed between screen transitions, we show the interstitial ad when a user clicks the CLOSE button.

Modify the onGameOver() method as follows:

lib/game_route.dart

@override
void onGameOver(int correctAnswers) {
  showDialog(
    context: _scaffoldKey.currentContext,
    builder: (context) {
      return AlertDialog(
        title: Text('Game over!'),
        content: Text('Score: $correctAnswers/5'),
        actions: <Widget>[
          FlatButton(
            child: Text('close'.toUpperCase()),
            onPressed: () {
              
              // TODO: Display an Interstitial Ad
              if (_isInterstitialAdReady) {
                _interstitialAd.show();
              }

              _moveToHome();
            },
          ),
        ],
      );
    },
  );
}

Finally, release the resource associated with the InterstitialAd object by calling the InterstitialAd.dispose() method in the dispose() callback method.

lib/game_route.dart

@override
void dispose() {
  ...

  // TODO: Dispose InterstitialAd object
  _interstitialAd?.dispose();

  ...

  super.dispose();
}

That's it! Run the project to see an interstitial ad displayed after the game finishes.

53f44b98e8a0c446.gif

In this section, you add a rewarded ad which gives a user an additional hint as a reward.

First, add the members and methods for the rewarded ad in the _GameRouteState class. Note that RewardedVideoAd is a singleton object, so you don't need to have a member for managing the instance of the RewardedVideoAd class.

RewardedVideoAdEvent.rewarded is the most important ad event in a rewarded ad. It's triggered when a user becomes eligible to receive a reward (for example., finished watching a video). In this codelab, RewardedVideoAdEvent.rewarded calls the QuizManager.instance.useHint() method which reveals one more character in the hint string.

Also, according to the ad event, RewardedVideoAdEvent.rewarded updates the UI by changing the value of _isRewardedAdReady. Note that _isRewardedAdReady reloads the ad when a user closes the ad, to make sure the ad is ready as early as possible.

lib/game_route.dart

class _GameRouteState extends State<GameRoute> implements QuizEventListener {

  ...

  // TODO: Add _isRewardedAdReady
  bool _isRewardedAdReady;

  ...

  // TODO: Implement _loadRewardedAd()
  void _loadRewardedAd() {
    RewardedVideoAd.instance.load(
      targetingInfo: MobileAdTargetingInfo(),
      adUnitId: AdManager.rewardedAdUnitId,
    );
  }

  // TODO: Implement _onRewardedAdEvent()
  void _onRewardedAdEvent(RewardedVideoAdEvent event,
      {String rewardType, int rewardAmount}) {
    switch (event) {
      case RewardedVideoAdEvent.loaded:
        setState(() {
          _isRewardedAdReady = true;
        });
        break;
      case RewardedVideoAdEvent.closed:
        setState(() {
          _isRewardedAdReady = false;
        });
        _loadRewardedAd();
        break;
      case RewardedVideoAdEvent.failedToLoad:
        setState(() {
          _isRewardedAdReady = false;
        });
        print('Failed to load a rewarded ad');
        break;
      case RewardedVideoAdEvent.rewarded:
        QuizManager.instance.useHint();
        break;
      default:
      // do nothing
    }
  }

  ...
}

Next, initialize _isRewardedAdReady and set _onRewardedAdEvent as an ad event listener. Then, call _loadRewardedAd() to request a rewarded ad.

lib/game_route.dart

@override
void initState() {
  ...

  // TODO: Initialize _isRewardedAdReady
  _isRewardedAdReady = false;
 
  // TODO: Set Rewarded Ad event listener
  RewardedVideoAd.instance.listener = _onRewardedAdEvent;

  // TODO: Load a Rewarded Ad
  _loadRewardedAd();
}

Next, allow users to watch a rewarded ad by clicking the floating action button. The button shows only if a user hasn't used a hint at the current level and a rewarded ad is loaded.

Modify the _buildFloatingActionButton() method, as follows, to display the floating action button. Note that returning null hides the button from the screen.

lib/game_route.dart

Widget _buildFloatingActionButton() {
  // TODO: Return a FloatingActionButton if a Rewarded Ad is available
  return (!QuizManager.instance.isHintUsed && _isRewardedAdReady)
      ? FloatingActionButton.extended(
          onPressed: () {
            showDialog(
              context: context,
              builder: (context) {
                return AlertDialog(
                  title: Text('Need a hint?'),
                  content: Text('Watch an Ad to get a hint!'),
                  actions: <Widget>[
                    FlatButton(
                      child: Text('cancel'.toUpperCase()),
                      onPressed: () {
                        Navigator.pop(context);
                      },
                    ),
                    FlatButton(
                      child: Text('ok'.toUpperCase()),
                      onPressed: () {
                        Navigator.pop(context);
                        RewardedVideoAd.instance.show();
                      },
                    ),
                  ],
                );
              },
            );
          },
          label: Text('Hint'),
          icon: Icon(Icons.card_giftcard),
        )
      : null;
}

Finally, remove the rewarded ad event listener in the dispose() callback method.

lib/game_route.dart

@override
void dispose() {
  ...

  // TODO: Remove Rewarded Ad event listener
  RewardedVideoAd.instance.listener = null;

  ...

  super.dispose();
}

That's it! Run the project and watch a rewarded ad, to get an additional hint.

2a79a3db6b44dae9.gif

9db81af632cb2b15.pngYou've found something special!

You have completed the codelab. You can find the completed code for this codelab in the android_studio_folder.pngcomplete folder.

To learn more, try the other Flutter codelabs.