Повторно используйте баннерную рекламу в прокручиваемых лентах.

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

На этой странице рассматриваются вопросы определения размера кэша рекламы, проверки того, находится ли экземпляр BannerAd за пределами экрана, и переназначения кэшированных объявлений на позиции в списках.

На следующем изображении показано, как баннерная реклама, находящаяся за пределами экрана, возвращается в кэш и повторно используется в позиции списка по мере прокрутки пользователем:

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

Предварительные требования

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

Отслеживание позиций в назначенном списке

При прокрутке пользователем баннера функция повторного использования сохраняет в памяти ограниченное количество экземпляров BannerAd и перемещает эти экземпляры между позициями в списке.

Чтобы определить, какие объявления следует использовать повторно, отслеживайте, какое место в списке занимает каждое объявление в кэше.

Сохраните в своем виджете следующее состояние:

  • Кэш фиксированного размера, содержащий экземпляры BannerAd . Размер кэша, который вы задаете, — это максимальное количество объявлений, одновременно хранящихся в памяти.
  • Интервал показа рекламы, определяющий частоту появления объявления в списке.
  • Класс Map , связывающий каждый экземпляр BannerAd с позицией в списке, которую он занимает. При повторном использовании объявления обновите запись в этом классе Map , указав на последнюю позицию.
  • Класс ` Map , который хранит определяемый платформой объект AdSize для каждого загруженного объявления. После загрузки объявления высота адаптивного баннера становится известна.

В следующем примере отслеживаются назначенные позиции в списке для каждого объявления в кэше:

// Maximum number of banner ad instances kept in the cache.
static const int _cacheSize = 8;

// Spacing between banner ads. For example, index 0, 6, 12, and so on
// display ads.
static const int _adInterval = 6;

// The cache of allocated BannerAd instances.
final List<BannerAd> _banners = [];

// Maps each BannerAd instance to its currently assigned list item position.
final Map<BannerAd, int> _bannerPositions = {};

// Stores the platform-resolved size of each loaded banner ad.
final Map<BannerAd, AdSize> _bannerSizes = {};

Выберите размер кэша

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

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

  1. Чтобы оценить, сколько рекламных объявлений поместится на экране одновременно, разделите высоту области просмотра на высоту одного рекламного интервала.
  2. Добавьте место для рекламы, которая продолжает отсоединяться при быстрой прокрутке.
  3. Если вы видите, что выбранные для повторного показа рекламные объявления по-прежнему отображаются на экране, увеличьте размер кэша.

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

Проверьте, отображается ли реклама на экране.

Все классы Google Mobile Ads Flutter Plugin , отображающие представления платформы, реализуют класс AdWithView и предоставляют геттер isMounted . Перед повторным назначением кэшированного объявления на позицию в списке проверьте геттер isMounted , чтобы убедиться, что объявление прокрутилось за пределы экрана и его можно безопасно использовать повторно.

Извлечь и утилизировать баннерную рекламу

Когда в списке запрашивается баннер для определенной позиции, выполните следующие действия:

  1. Если такое объявление уже размещено, используйте его повторно.
  2. Если кэш не заполнен, запросите показ рекламы.
  3. Если кэш заполнен, выберите кэшированное объявление и убедитесь, что значение геттера isMounted равно false , прежде чем повторно назначать объявление.
  4. При удалении виджета из дерева виджетов вызовите метод dispose() для каждого объявления в кэше.

В следующем примере отображается и повторно используется баннерная реклама:

BannerAd _getRecycledBannerAd(BuildContext context, int bannerPosition) {
  // 1. If an ad is already mapped to this position, reuse it.
  final BannerAd? existingBanner = _bannerPositions.entries
      .firstWhereOrNull((entry) => entry.value == bannerPosition)
      ?.key;
  if (existingBanner != null) {
    return existingBanner;
  }

  // 2. If the cache is not full, allocate a new ad instance.
  if (_banners.length < _cacheSize) {
    final BannerAd newBanner = _createBannerAd(context);
    _banners.add(newBanner);
    _bannerPositions[newBanner] = bannerPosition;
    return newBanner;
  }

  // 3. Select an existing ad from the cache using modulo arithmetic.
  final BannerAd targetBanner = _banners[bannerPosition % _cacheSize];

  // 4. Verify the ad is detached from the screen before recycling.
  if (targetBanner.isMounted) {
    // If still on screen during fast scrolls, allocate a temporary instance.
    return _createBannerAd(context);
  } else {
    // Safe to reuse: reassign to the new position.
    _bannerPositions[targetBanner] = bannerPosition;
    return targetBanner;
  }
}

Полный пример см. в разделе «Пример Google Mobile Ads Flutter Plugin .