Как использовать встроенные адаптивные баннеры для прокручиваемых баннеров

Адаптивные баннеры – это новое поколение адаптивных объявлений, которые позволяют повысить эффективность рекламы за счет оптимизации размера объявлений для каждого устройства. Адаптивные баннеры, в отличие от баннеров фиксированного размера, поддерживают не только фиксированную высоту, но и фиксированную ширину.

При подборе размера во встроенных адаптивных баннерах учитывается максимальная, а не фиксированная высота. Это позволяет повысить эффективность.

Когда использовать встроенные адаптивные баннеры

Встроенные адаптивные баннеры больше и выше, чем фиксированные. Они имеют переменную высоту и могут занимать весь экран устройства.

Они предназначены для размещения в контенте с прокруткой, например:

Требования

Прежде чем продолжить, настройте Google Mobile Ads Flutter Plugin.

Подготовка

При добавлении адаптивных баннеров в приложение учитывайте следующие моменты:

  • Убедитесь, что вы используете последнюю версию Google Mobile Ads Flutter Plugin, а если вы используете медиацию AdMob, то и последние версии адаптеров медиации.

  • Встроенные адаптивные баннеры лучше всего работают, когда занимают всю доступную ширину. В большинстве случаев она равна ширине экрана устройства. Обязательно учитывайте безопасные зоны.

  • Получить размер объявления можно следующими способами:

    • AdSize.getCurrentOrientationInlineAdaptiveBannerAdSize(int width)
    • AdSize.getLandscapeInlineAdaptiveBannerAdSize(int width)
    • AdSize.getPortraitInlineAdaptiveBannerAdSize(int width)
    • AdSize.getInlineAdaptiveBannerAdSize(int width, int maxHeight)
  • При использовании встроенных адаптивных баннеров API Google Mobile Ads Flutter Pluginвозвращает AdSize с заданной шириной и встроенным флагом. Высота равна нулю или maxHeight в зависимости от того, какой API вы используете. Фактическая высота объявления становится доступна, когда оно возвращается.

  • Встроенный адаптивный баннер предназначен для размещения в контенте с прокруткой. Высота баннера может быть равна высоте экрана устройства или ограничена максимальным значением в зависимости от API.

Реализация

Чтобы реализовать простой встроенный адаптивный баннер, выполните следующие действия:

  1. Как получить размер встроенного адаптивного баннера Это значение будет использоваться для запроса адаптивного баннера. Чтобы получить адаптивный размер объявления, убедитесь, что вы:
    1. Получите ширину используемого устройства в независимых от плотности пикселях или задайте собственную ширину, если вы не хотите использовать всю ширину экрана. Чтобы получить ширину экрана, можно использовать MediaQuery.of(context).
    2. Используйте подходящие статические методы класса размера объявления, например AdSize.getCurrentOrientationInlineAdaptiveBannerAdSize(int width) чтобы получить встроенный адаптивный объект AdSize для текущей ориентации.
    3. Если вы хотите ограничить высоту баннера, используйте статический метод AdSize.getInlineAdaptiveBannerAdSize(int width, int maxHeight).
  2. Создайте объект 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();
  }
}