インライン アダプティブ バナー

次世代のレスポンシブ広告であるアダプティブ バナーは、デバイスごとに広告サイズを最適化して広告の効果を高めます。アダプティブ バナーは固定サイズのバナーが改良されたもので、固定サイズのバナー広告の高さが固定されているのに対し、アダプティブ バナーではデベロッパーが指定する広告の幅に応じて、自動的に最適な広告サイズが決定されます。

最適な広告サイズが選択されるように、インライン アダプティブ バナーでは固定された高さではなく、最大高さが使用されます。これにより、パフォーマンスの向上が見込めます。

インライン アダプティブ バナーの用途

インライン アダプティブ バナーは、アンカー アダプティブ バナーよりも大きく縦長です。インライン アダプティブ バナーでは高さが変動するため、デバイス画面と同じ大きさで表示できます。

次のような、スクロール型コンテンツに配置するためのものです。

前提条件

始める前に

アプリにアダプティブ バナーを実装する際には、次の点に注意してください。

  • 使用する Google Mobile Ads SDK が最新バージョンであることを確認し、メディエーションを使用する場合には、最新バージョンのメディエーション アダプタを使用してください。

  • インライン アダプティブ バナーは、利用できるスペースの横幅いっぱいに表示すると最も効果を発揮するように設計されています。ほとんどの場合、使用するデバイスの画面の全幅になります。適切な安全領域を考慮してください。

  • 広告サイズを取得する方法は次のとおりです。

    • AdSize.getCurrentOrientationInlineAdaptiveBannerAdSize(int width)
    • AdSize.getLandscapeInlineAdaptiveBannerAdSize(int width)
    • AdSize.getPortraitInlineAdaptiveBannerAdSize(int width)
    • AdSize.getInlineAdaptiveBannerAdSize(int width, int maxHeight)
  • インライン アダプティブ バナー API を使用している場合、Google Mobile Ads SDK は指定された幅とインライン フラグが設定された AdSize を返します。高さは、使用している API に応じて 0 または maxHeight になります。広告の実際の高さは、返された値で確認できます。

  • インライン アダプティブ バナーは、スクロール可能なコンテンツに配置されるよう設計されています。バナーの高さは、API に応じて、デバイス画面と同じ大きさか、最大高さの制限値となります。

実装

シンプルなインライン アダプティブ バナーを実装する手順は次のとおりです。

  1. インライン アダプティブ バナーの広告サイズを取得します。取得したサイズは、アダプティブ バナーのリクエストに使用します。アダプティブ広告のサイズを取得する手順は次のとおりです。
    1. 使用するデバイスの幅を密度非依存ピクセルから取得するか、画面の全幅を使用しない場合は独自の幅を設定します。MediaQuery.of(context) を使用して、画面の幅を取得します。
    2. 広告サイズクラスの適切な静的メソッド(AdSize.getCurrentOrientationInlineAdaptiveBannerAdSize(int width) など)を使用して、指定した向きのインライン アダプティブ バナーの AdSize オブジェクトを取得します。
    3. バナーの高さを制限する場合は、静的メソッド AdSize.getInlineAdaptiveBannerAdSize(int width, int maxHeight) を使用できます。
  2. 広告ユニット ID、アダプティブ バナーのサイズ、広告リクエスト オブジェクトを設定して BannerAd オブジェクトを作成します。
  3. 広告を読み込みます。
  4. onAdLoaded コールバックで、BannerAd.getPlatformAdSize() を使用して更新されたプラットフォーム広告サイズを取得し、AdWidget コンテナの高さを更新します。

サンプルコード

次に、画面の幅に合わせてインライン アダプティブ バナーを読み込むウィジェットの例を示します。インセットも考慮されています。

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

/// This example demonstrates inline adaptive banner ads.
///
/// Loads and shows an inline adaptive banner ad in a scrolling view,
/// and reloads the ad when the orientation changes.
class InlineAdaptiveExample extends StatefulWidget {
  @override
  _InlineAdaptiveExampleState createState() => _InlineAdaptiveExampleState();
}

class _InlineAdaptiveExampleState extends State<InlineAdaptiveExample> {
  static const _insets = 16.0;
  BannerAd? _inlineAdaptiveAd;
  bool _isLoaded = false;
  AdSize? _adSize;
  late Orientation _currentOrientation;

  double get _adWidth => MediaQuery.of(context).size.width - (2 * _insets);

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _currentOrientation = MediaQuery.of(context).orientation;
    _loadAd();
  }

  void _loadAd() async {
    await _inlineAdaptiveAd?.dispose();
    setState(() {
      _inlineAdaptiveAd = null;
      _isLoaded = false;
    });

    // Get an inline adaptive size for the current orientation.
    AdSize size = AdSize.getCurrentOrientationInlineAdaptiveBannerAdSize(
        _adWidth.truncate());

    _inlineAdaptiveAd = BannerAd(
      // TODO: replace this test ad unit with your own ad unit.
      adUnitId: 'ca-app-pub-3940256099942544/9214589741',
      size: size,
      request: AdRequest(),
      listener: BannerAdListener(
        onAdLoaded: (Ad ad) async {
          print('Inline adaptive banner loaded: ${ad.responseInfo}');

          // After the ad is loaded, get the platform ad size and use it to
          // update the height of the container. This is necessary because the
          // height can change after the ad is loaded.
          BannerAd bannerAd = (ad as BannerAd);
          final AdSize? size = await bannerAd.getPlatformAdSize();
          if (size == null) {
            print('Error: getPlatformAdSize() returned null for $bannerAd');
            return;
          }

          setState(() {
            _inlineAdaptiveAd = bannerAd;
            _isLoaded = true;
            _adSize = size;
          });
        },
        onAdFailedToLoad: (Ad ad, LoadAdError error) {
          print('Inline adaptive banner failedToLoad: $error');
          ad.dispose();
        },
      ),
    );
    await _inlineAdaptiveAd!.load();
  }

  /// Gets a widget containing the ad, if one is loaded.
  ///
  /// Returns an empty container if no ad is loaded, or the orientation
  /// has changed. Also loads a new ad if the orientation changes.
  Widget _getAdWidget() {
    return OrientationBuilder(
      builder: (context, orientation) {
        if (_currentOrientation == orientation &&
            _inlineAdaptiveAd != null &&
            _isLoaded &&
            _adSize != null) {
          return Align(
              child: Container(
            width: _adWidth,
            height: _adSize!.height.toDouble(),
            child: AdWidget(
              ad: _inlineAdaptiveAd!,
            ),
          ));
        }
        // Reload the ad if the orientation changes.
        if (_currentOrientation != orientation) {
          _currentOrientation = orientation;
          _loadAd();
        }
        return Container();
      },
    );
  }

  @override
  Widget build(BuildContext context) => Scaffold(
      appBar: AppBar(
        title: Text('Inline adaptive banner example'),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: _insets),
          child: ListView.separated(
            itemCount: 20,
            separatorBuilder: (BuildContext context, int index) {
              return Container(
                height: 40,
              );
            },
            itemBuilder: (BuildContext context, int index) {
              if (index == 10) {
                return _getAdWidget();
              }
              return Text(
                'Placeholder text',
                style: TextStyle(fontSize: 24),
              );
            },
          ),
        ),
      ));

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