Banner

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.

This guide gets you started with anchored adaptive banner ads. Anchored adaptive banners optimizes the ad size for each device using an ad width you specify.

Anchored adaptive banner ads are fixed aspect ratio ads rather than fixed size ads. The aspect ratio is similar to 320x50. Once you specify the full width available, the Google Mobile Ads SDK returns an ad with optimal height for that width. The optimal height for the ad remains constant across different ad requests, and the content surrounding the ad stays in place when the ad refreshes.

Always test with test ads

When building and testing your apps, make sure you use test ads rather than live, production ads. Failure to do so can lead to suspension of your account.

The easiest way to load test ads is to use our dedicated test ad unit ID for banners:

Android

ca-app-pub-3940256099942544/9214589741

iOS

ca-app-pub-3940256099942544/2435281174

The test ad units are configured to return test ads for every request, and you're free to use them in your own apps while coding, testing, and debugging. Just make sure you replace them with your own ad unit IDs before publishing your app.

Get the ad size

To request a banner ad with the correct ad size, follow these steps:

  1. Get the width of the device's screen in density-independent pixels (dp) using MediaQuery.of(context). If you don't want to use the full screen width, you can set your own width.

  2. Use the appropriate static method on the AdSize class to get an AdSize object. For example, use AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(int width) to get the ad size for the current orientation.

// Get an AnchoredAdaptiveBannerAdSize before loading the ad.
final size = await AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(
    MediaQuery.sizeOf(context).width.truncate());

Load an ad

The following example instantiates a banner ad:

class BannerExampleState extends State<BannerExample>{
  BannerAd? _bannerAd;
  bool _isLoaded = false;

  // TODO: replace this test ad unit with your own ad unit.
  final adUnitId = Platform.isAndroid
    ? 'ca-app-pub-3940256099942544/9214589741'
    : 'ca-app-pub-3940256099942544/2435281174';

  /// Loads a banner ad.
  void loadAd() async {
    // Get an AnchoredAdaptiveBannerAdSize before loading the ad.
    final size = await AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(
        MediaQuery.sizeOf(context).width.truncate());

    _bannerAd = BannerAd(
      adUnitId: adUnitId,
      request: const AdRequest(),
      size: size,
      listener: BannerAdListener(
        // Called when an ad is successfully received.
        onAdLoaded: (ad) {
          debugPrint('$ad loaded.');
          setState(() {
            _isLoaded = true;
          });
        },
        // Called when an ad request failed.
        onAdFailedToLoad: (ad, err) {
          debugPrint('BannerAd failed to load: $error');
          // Dispose the ad here to free resources.
          ad.dispose();
        },
      ),
    )..load();
  }
}

Through the use of BannerAdListener, you can listen for lifecycle events, such as when an ad is loaded. This example implements each method and logs a message to the console:

class BannerExampleState extends State<BannerExample> {
  BannerAd? _bannerAd;
  bool _isLoaded = false;

  // TODO: replace this test ad unit with your own ad unit.
  final adUnitId = Platform.isAndroid
    ? 'ca-app-pub-3940256099942544/9214589741'
    : 'ca-app-pub-3940256099942544/2435281174';


  /// Loads a banner ad.
  void loadAd() async {
    // Get an AnchoredAdaptiveBannerAdSize before loading the ad.
    final size = await AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(
        MediaQuery.sizeOf(context).width.truncate());

    _bannerAd = BannerAd(
      adUnitId: adUnitId,
      request: const AdRequest(),
      size: size,
      listener: BannerAdListener(
        // Called when an ad is successfully received.
        onAdLoaded: (ad) {
          debugPrint('$ad loaded.');
          setState(() {
            _isLoaded = true;
          });
        },
        // Called when an ad request failed.
        onAdFailedToLoad: (ad, err) {
          debugPrint('BannerAd failed to load: $error');
          // Dispose the ad here to free resources.
          ad.dispose();
        },
        // Called when an ad opens an overlay that covers the screen.
        onAdOpened: (Ad ad) {},
        // Called when an ad removes an overlay that covers the screen.
        onAdClosed: (Ad ad) {},
        // Called when an impression occurs on the ad.
        onAdImpression: (Ad ad) {},
      ),
    )..load();
  }
}

Refresh an ad

If you configured your ad unit to refresh, you don't need to request another ad when the ad fails to load. The Google Mobile Ads SDK respects any refresh rate you specified in the AdMob UI. If you haven't enabled refresh, issue a new request. For more details on ad unit refresh, such as setting a refresh rate, see Use automatic refresh for Banner ads.

Display a banner ad

To display a BannerAd as a widget, you must instantiate an AdWidget with a supported ad after calling load(). You can create the widget before calling load(), but load() must be called before adding it to the widget tree.

AdWidget inherits from Flutter's Widget class and can be used like any other widget. On iOS, make sure you place the widget in a widget with a specified width and height. Otherwise, your ad may not be displayed. A BannerAd can be placed in a container with a size that matches the ad:

if (_bannerAd != null) {
  Align(
    alignment: Alignment.bottomCenter,
    child: SafeArea(
      child: SizedBox(
        width: _bannerAd!.size.width.toDouble(),
        height: _bannerAd!.size.height.toDouble(),
        child: AdWidget(ad: _bannerAd!),
      ),
    ),
  )
}

An ad must be disposed when access to it is no longer needed. The best practice for when to call dispose() is either after the AdWidget is removed from the widget tree or in the BannerAdListener.onAdFailedToLoad() callback.

That's it! Your app is now ready to display banner ads.

Scrolling limitation on Android 9 and below

We are aware that some older or less powerful devices running Android 9 or earlier may have suboptimal performance when displaying inline banner ads within scrolling views. We recommend only using these types of banners on Android 10 or later. Fixed position banners such as anchored banners are not affected and can be used with optimal performance on all Android API levels.

Complete example on GitHub

See a full example of the banner integration covered in this page in banner_example.

Learn about other banner types

Familiarize yourself with other types of banners defined in this section for your Flutter application.

Inline adaptive banners

Inline adaptive banners have variable height and are larger, taller banners compared to anchored adaptive banners. Inline adaptive banners are recommended over anchored adaptive banner ads for apps that place banner ads in scrollable content. For more details, see inline adaptive banners.

Collapsible banners

Collapsible banner ads are banner ads that are initially presented as a larger overlay, with a button to collapse the ad to a smaller size. Consider using this banner to further optimize your performance. For more details, see collapsible banner ads.