Адаптивный баннер

Виды адаптивных баннеров

В Yandex Mobile Ads SDK есть два вида адаптивных баннеров:

Баннер

Описание

Когда использовать

Sticky

Баннер-липучка, который примыкает к краю экрана и появляется поверх других элементов. Устойчивый к прокрутке.

Когда баннер должен «приклеиться» и находиться поверх контента даже при прокрутке.

Inline

Баннер, который встраивается как элемент UI — в списки, контент и т. д.

Когда баннер должен быть частью контента: в ленте новостей, между постами, как элемент списка.

Все виды автоматически обновляют креатив каждые 60 секунд.

Совет

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

Программно виды отличаются лишь тем, как задается их размер. Примеры:

BannerAdSize.StickySize(width: number)
BannerAdSize.InlineSize(width: number, maxHeight: number)

Сущность

Описание

BannerAdSize

Высота баннера должна:

  • не превышать 15% от высоты экрана;

  • составлять не менее 50 dp.

Все размеры баннера должны передаваться строго в dp.

adUnitId

Используйте:

  • development mode — для работы с демоблоками;

  • production mode — для работы с R-M-XXXXXX-Y (уточните реальный ID в интерфейсе Рекламной сети Яндекса). R-M-XXXXXX-Y — это вид рабочего рекламного ID, по которому будут приходить разные креативы.

Пример создания адаптивного баннера

import React, { useEffect, useState } from 'react';
import { ActivityIndicator, Alert, Dimensions, StyleSheet, Text, View } from 'react-native';
import { AdRequest, AdTheme, BannerAdSize, BannerView, Gender, Location } from 'yandex-mobile-ads';

const BANNER_AD_UNIT_ID = 'demo-banner-yandex';

export default function BannerAd() {
  const [adLoaded, setAdLoaded] = useState(false);
  const [adSize, setAdSize] = useState<BannerAdSize | null>(null);
  const [error, setError] = useState<Error | string | null>(null);
  const [screenWidth, setScreenWidth] = useState(Dimensions.get('window').width);

  useEffect(() => {
    const subscription = Dimensions.addEventListener('change', ({ window }) => {
      setScreenWidth(window.width);
    });
    return () => subscription?.remove();
  }, []);

  useEffect(() => {
      console.log('🔍 Creating banner size for width:', screenWidth);
      
      BannerAdSize.stickySize(screenWidth)
        .then((size) => {
          console.log('✅ Banner size created:', size);
          setAdSize(size);
        })
        .catch((err) => {
          console.error('❌ Failed to create banner size:', err);
          setError(err);
        });

    return () => {};
  }, [screenWidth]);

  const adRequest = new AdRequest({
    age: '20',
    contextQuery: 'context-query',
    contextTags: ['context-tag'],
    gender: Gender.Male,
    location: new Location(55.734202, 37.588063),
    adTheme: AdTheme.Light,
    parameters: new Map<string, string>([
      ['param1', 'value1'],
      ['param2', 'value2']
    ]),
  });

  if (error) {
    return (
      <View style={styles.container}>
        <Text style={styles.title}>Banner Ad</Text>
        <Text style={styles.errorText}>
          ❌ Error: {error instanceof Error ? error.message : String(error)}
        </Text>
        <Text style={styles.hintText}>
          Make sure you are NOT using Expo Go!{'\n'}
          Run: <Text style={styles.codeText}>npx expo run:ios</Text>
        </Text>
      </View>
    );
  }

  if (!adSize) {
    return (
      <View style={styles.container}>
        <Text style={styles.title}>Banner Ad</Text>
        <ActivityIndicator size="large" color="#007AFF" />
        <Text style={styles.status}>⏳ Preparing banner...</Text>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Banner Ad</Text>
      <Text style={styles.status}>
        {adLoaded ? '✅ Ad Loaded' : '⏳ Loading...'}
      </Text>

      <View style={[styles.adContainer, { width: adSize.width, height: adSize.height }]}>
        <BannerView
          adUnitId={BANNER_AD_UNIT_ID}
          adRequest={adRequest}
          size={adSize}
          onAdLoaded={() => {
            setAdLoaded(true);
            console.log('✅ Banner ad loaded');
          }}
          onAdFailedToLoad={(error: any) => {
            console.error('❌ Banner ad failed:', error);
            Alert.alert('Ad Failed', error?.message || 'Unknown error');
          }}
          onAdClicked={() => console.log('👆 Banner clicked')}
          onAdImpression={(data: any) => console.log('👁️ Impression:', data)}
        />
      </View>

      <Text style={styles.sizeInfo}>
        Size: {adSize.width}x{adSize.height} dp
      </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f5f5f5',
    padding: 20,
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
  },
  status: {
    fontSize: 16,
    marginBottom: 20,
    color: '#666',
  },
  adContainer: {
    backgroundColor: '#fff',
    borderRadius: 10,
    overflow: 'hidden',
    marginVertical: 20,
  },
  sizeInfo: {
    fontSize: 12,
    color: '#999',
    marginTop: 10,
  },
  errorText: {
    fontSize: 14,
    color: '#f00',
    textAlign: 'center',
    padding: 20,
  },
  hintText: {
    fontSize: 12,
    color: '#666',
    textAlign: 'center',
    marginTop: 10,
  },
  codeText: {
    fontFamily: 'monospace',
    backgroundColor: '#e0e0e0',
    padding: 4,
  },
});

Проверка интеграции

Проверить работу рекламных форматов можно на нашем демо-проекте.