Добавление баннера AdMob и встроенной рекламы в приложение Flutter

1. Введение

В этой лаборатории кода вы реализуете баннер AdMob и встроенную рекламу AdMob в приложении Flutter.

Что ты построишь

В этой лаборатории кода вы узнаете, как реализовать встроенный баннер AdMob и встроенные встроенные объявления AdMob в приложении Flutter с помощью плагина Google Mobile Ads для Flutter.

Если у вас возникнут какие-либо проблемы (ошибки в коде, грамматические ошибки, нечеткие формулировки и т. д.) при работе с этой кодовой лабораторией, сообщите о проблеме, используя ссылку Сообщить об ошибке в нижнем левом углу кодовой лаборатории.

Что вы узнаете

  • Как настроить плагин Google Mobile Ads Flutter
  • Как реализовать встроенный баннер и рекламу с вознаграждением в приложении Flutter

Что вам понадобится

  • Android Studio 4.1 или новее
  • Xcode 12 или новее (для разработки под iOS)

Как бы вы оценили свой опыт работы с AdMob?

Новичок Средний Опытный

Как бы вы оценили свой уровень опыта работы с Flutter?

Новичок Средний Опытный

2. Настройте среду разработки Flutter.

Для выполнения этой лабораторной работы вам понадобятся два программного обеспечения — Flutter SDK и редактор .

Вы можете запустить кодовую лабораторию, используя любое из этих устройств:

  • Физическое устройство Android или iOS , подключенное к вашему компьютеру и переведенное в режим разработчика.
  • Симулятор iOS (требуется установка инструментов Xcode).
  • Эмулятор Android (требуется установка в Android Studio).
  • Браузер (для отладки необходим Chrome).
  • В качестве настольного приложения для Windows , Linux или macOS . Вы должны разрабатывать на платформе, на которой планируете развернуть. Итак, если вы хотите разработать классическое приложение для Windows, вам необходимо разработать его в Windows, чтобы получить доступ к соответствующей цепочке сборки. Существуют требования, специфичные для операционной системы, которые подробно описаны на docs.flutter.dev/desktop .

Загрузите код

После загрузки zip-файла извлеките его содержимое. У вас будет папка с именем admob-inline-ads-in-flutter-main .

Альтернативно вы можете клонировать репозиторий GitHub из командной строки:

$ git clone https://github.com/googlecodelabs/admob-inline-ads-in-flutter

Репозиторий содержит три папки:

  • android_studio_folder.png starter: Начальный код, который вы создадите в этой лаборатории кода.
  • android_studio_folder.png Complete: завершенный код для этой лаборатории. (Java и Objective-C для собственного кода)
  • android_studio_folder.png Complete_kotlin_swift: завершенный код для этой лаборатории. (Kotlin и Swift для собственного кода)

3. Настройте приложение AdMob и рекламные блоки.

Поскольку Flutter — это многоплатформенный SDK, вам необходимо добавить в AdMob приложение и рекламные блоки как для Android, так и для iOS.

Настройка для Android

Чтобы настроить Android, вам необходимо добавить приложение Android и создать рекламные блоки.

Добавить приложение для Android

  1. В консоли AdMob нажмите «ДОБАВИТЬ ПРИЛОЖЕНИЕ» в меню «Приложения» .
  2. Когда вас спросят , опубликовали ли вы свое приложение в Google Play или App Store? , нажмите НЕТ .
  3. Введите AdMob inline ads в поле названия приложения и выберите Android в качестве платформы.

d51828db0e2e4f6c.png

  1. Для завершения этой лаборатории не требуется включение пользовательских метрик. Однако мы рекомендуем вам это сделать, поскольку это позволит вам более детально понять поведение пользователя. Нажмите ДОБАВИТЬ , чтобы завершить процесс.

b918bf44362813a9.png

Создать рекламные блоки

Чтобы добавить рекламные блоки:

  1. Выберите приложение для встроенных объявлений AdMob в меню «Приложения» в консоли AdMob .
  2. Откройте меню «Рекламные блоки» .

Баннер

  1. Нажмите «ДОБАВИТЬ РЕКЛАМНЫЙ БЛОК» .
  2. Выберите Баннер в качестве формата.
  3. Введите android-inline-banner в поле «Название рекламного блока» .
  4. Нажмите СОЗДАТЬ РЕКЛАМНЫЙ БЛОК , чтобы завершить процесс.

Родной

  1. Нажмите «ДОБАВИТЬ РЕКЛАМНЫЙ БЛОК» .
  2. В качестве формата выберите Native Advanced .
  3. Введите android-inline-native в поле «Название рекламного блока» .
  4. Нажмите СОЗДАТЬ РЕКЛАМНЫЙ БЛОК , чтобы завершить процесс.

Обычно новому рекламному блоку требуется несколько часов, чтобы начать показ объявлений.

Если вы хотите немедленно протестировать поведение объявления, используйте идентификатор тестового приложения и идентификаторы рекламных блоков, указанные в таблицах «Идентификатор приложения для Android/идентификатор рекламного блока» и «Идентификатор приложения для iOS/идентификатор рекламного блока».

Настройка для iOS

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

Добавить приложение для iOS

  1. В консоли AdMob нажмите «ДОБАВИТЬ ПРИЛОЖЕНИЕ» в меню «Приложения» .
  2. Когда вас спросят , опубликовали ли вы свое приложение в Google Play или App Store? , нажмите НЕТ .
  3. Введите AdMob inline ads в поле названия приложения и выберите iOS в качестве платформы.

a4c963c9aa09519.png

  1. Для завершения этой лаборатории не требуется включение пользовательских метрик. Однако мы рекомендуем вам это сделать, поскольку это позволит вам более детально понять поведение пользователя. Нажмите ДОБАВИТЬ , чтобы завершить процесс.

b918bf44362813a9.png

Создать рекламные блоки

Чтобы добавить рекламные блоки:

  1. Выберите приложение для встроенных объявлений AdMob в меню «Приложения» в консоли AdMob .
  2. Откройте меню «Рекламные блоки» .

Баннер

  1. Нажмите «ДОБАВИТЬ РЕКЛАМНЫЙ БЛОК» .
  2. Выберите Баннер в качестве формата.
  3. Введите ios-inline-banner в поле «Название рекламного блока» .
  4. Нажмите СОЗДАТЬ РЕКЛАМНЫЙ БЛОК , чтобы завершить процесс.

Родной

  1. Нажмите «ДОБАВИТЬ РЕКЛАМНЫЙ БЛОК» .
  2. В качестве формата выберите Native Advanced .
  3. Введите ios-inline-native в поле «Название рекламного блока» .
  4. Нажмите СОЗДАТЬ РЕКЛАМНЫЙ БЛОК , чтобы завершить процесс.

Обычно новому рекламному блоку требуется несколько часов, чтобы начать показ объявлений.

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

Необязательно: используйте тестовое приложение AdMob и рекламные блоки.

Если вы хотите следовать кодовой лаборатории вместо того, чтобы создавать новое приложение и рекламные блоки самостоятельно, вы можете использовать тестовый идентификатор приложения AdMob и идентификаторы рекламных блоков, перечисленные в следующих таблицах.

Идентификатор приложения Android/идентификатор рекламного блока

Элемент

Идентификатор приложения/идентификатор рекламного блока

Идентификатор приложения Рекламы в приложении

ca-app-pub-3940256099942544~3347511713

Баннер

ca-app-pub-3940256099942544/6300978111

Родной

ca-app-pub-3940256099942544/2247696110

Идентификатор приложения iOS/идентификатор рекламного блока

Элемент

Идентификатор приложения/идентификатор рекламного блока

Идентификатор приложения Рекламы в приложении

ca-app-pub-3940256099942544~1458002511

Баннер

ca-app-pub-3940256099942544/2934735716

Родной

ca-app-pub-3940256099942544/3986624511

Дополнительные сведения о тестовых объявлениях см. в тестовых объявлениях для Android и документации для разработчиков тестовых объявлений для iOS .

4. Добавьте плагин Google Mobile Ads Flutter.

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

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

Поскольку Flutter — это мультиплатформенный SDK, плагин google_mobile_ads применим как для iOS, так и для Android. Итак, если вы добавите плагин в свое приложение Flutter, он будет использоваться версиями приложения встроенной рекламы AdMob как для Android, так и для iOS.

Добавьте плагин Google Mobile Ads в качестве зависимости.

Чтобы получить доступ к API AdMob из проекта встроенных объявлений AdMob , добавьте google_mobile_ads в качестве зависимости к файлу pubspec.yaml , расположенному в корне проекта.

pubspec.yaml

...
dependencies:
  flutter:
    sdk: flutter
  google_fonts: ^0.3.9

  # TODO: Add google_mobile_ads as a dependency
  google_mobile_ads: ^1.2.0

...

Нажмите «Pub get» , чтобы установить плагин в проект встроенных объявлений AdMob .

93ef6061e58ebc86.png

Обновите AndroidManifest.xml (Android)

  1. Откройте файл android/app/src/main/AndroidManifest.xml в Android Studio.
  2. Добавьте идентификатор приложения AdMob, добавив тег <meta-data> с именем com.google.android.gms.ads.APPLICATION_ID . Например, если идентификатор вашего приложения AdMob — ca-app-pub-3940256099942544~3347511713 , вам необходимо добавить следующие строки в файл AndroidManifest.xml .

AndroidManifest.xml

<manifest>
    ...
    <application>
       ...
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-3940256099942544~3347511713"/>
    </application>

</manifest>

Обновить Info.plist (iOS)

  1. Откройте файл ios/Runner/Info.plist в Android Studio.
  2. Добавьте ключ GADApplicationIdentifier со строковым значением идентификатора вашего приложения AdMob. Например, если идентификатор вашего приложения AdMob — ca-app-pub-3940256099942544~1458002511 , вам необходимо добавить следующие строки в файл Info.plist .

iOS/Runner/Info.plist

...
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-3940256099942544~1458002511</string>
...

5. Добавьте вспомогательный класс для рекламы

Создайте новый файл с именем ad_helper.dart в каталоге lib . Затем реализуйте класс AdHelper , который предоставляет идентификатор приложения AdMob и идентификаторы рекламных блоков для Android и iOS.

Обязательно замените идентификатор приложения AdMob ( ca-app-pub-xxxxxx~yyyyy ) и идентификатор рекламного блока ( ca-app-pub-xxxxxxx/yyyyyyyy ) на идентификаторы, созданные на предыдущем шаге.

ad_helper.dart

import 'dart:io';

class AdHelper {

  static String get bannerAdUnitId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_BANNER_AD_UNIT_ID";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_BANNER_AD_UNIT_ID>";
    } else {
      throw UnsupportedError("Unsupported platform");
    }
  }

  static String get nativeAdUnitId {
    if (Platform.isAndroid) {
      return "<YOUR_ANDROID_NATIVE_AD_UNIT_ID>";
    } else if (Platform.isIOS) {
      return "<YOUR_IOS_NATIVE_AD_UNIT_ID>";
    } else {
      throw UnsupportedError("Unsupported platform");
    }
  }
}

Используйте следующий фрагмент кода, если вы хотите использовать тестовый идентификатор приложения AdMob и тестовые идентификаторы рекламных блоков.

ad_helper.dart

import 'dart:io';

class AdHelper {
  
  static String get bannerAdUnitId {
    if (Platform.isAndroid) {
      return 'ca-app-pub-3940256099942544/6300978111';
    } else if (Platform.isIOS) {
      return 'ca-app-pub-3940256099942544/2934735716';
    }
    throw UnsupportedError("Unsupported platform");
  }

  static String get nativeAdUnitId {
    if (Platform.isAndroid) {
      return 'ca-app-pub-3940256099942544/2247696110';
    } else if (Platform.isIOS) {
      return 'ca-app-pub-3940256099942544/3986624511';
    }
    throw UnsupportedError("Unsupported platform");
  }
}

6. Инициализируйте SDK Google Mobile Ads.

Перед загрузкой рекламы необходимо инициализировать Google Mobile Ads SDK. Откройте файл lib/home_page.dart и измените _initGoogleMobileAds() чтобы инициализировать SDK перед загрузкой домашней страницы.

Обратите внимание, что вам необходимо изменить тип возвращаемого значения метода _initGoogleMobileAds() с Future<dynamic> на Future<InitializationStatus> , чтобы получить результат инициализации SDK после ее завершения.

home_page.dart

// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';

import 'package:flutter/material.dart';

...

class HomePage extends StatelessWidget {

  ...

  Future<InitializationStatus> _initGoogleMobileAds() {
    // TODO: Initialize Google Mobile Ads SDK
    return MobileAds.instance.initialize();
  }
}

7. Добавьте рекламный баннер

В этом разделе вы отображаете рекламный баннер в середине списка, как показано на следующем снимке экрана.

62c405c962909fd3.png

  1. Откройте файл lib/banner_inline_page.dart .
  2. Импортируйте ad_helper.dart и google_mobile_ads.dart добавив следующие строки:
...

// TODO: Import ad_helper.dart
import 'package:admob_inline_ads_in_flutter/ad_helper.dart';

// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';

class BannerInlinePage extends StatefulWidget {
  ...
}
  1. В класс _BannerInlinePageState добавьте следующие члены и методы для рекламного баннера.

Обратите внимание, что _kAdIndex указывает индекс, в котором будет отображаться рекламный баннер, и используется для расчета индекса элемента из метода _getDestinationItemIndex() .

баннер_inline_page.dart

class _BannerInlinePageState extends State<BannerInlinePage> {

  // TODO: Add _kAdIndex
  static final _kAdIndex = 4;

  // TODO: Add a banner ad instance
  BannerAd? _ad;

  ...

  // TODO: Add _getDestinationItemIndex()
  int _getDestinationItemIndex(int rawIndex) {
    if (rawIndex >= _kAdIndex && _ad != null) {
      return rawIndex - 1;
    }
    return rawIndex;
  }

  ...
}
  1. В методе initState() создайте и загрузите BannerAd для баннера 320x50 ( AdSize.banner ). Обратите внимание, что прослушиватель рекламных событий настроен на обновление пользовательского интерфейса ( setState() ) при загрузке объявления.

баннер_inline_page.dart

@override
void initState() {
  super.initState();

  // TODO: Load a banner ad
  BannerAd(
    adUnitId: AdHelper.bannerAdUnitId,
    size: AdSize.banner,
    request: AdRequest(),
    listener: BannerAdListener(
      onAdLoaded: (ad) {
        setState(() {
          _ad = ad as BannerAd;
        });
      },
      onAdFailedToLoad: (ad, error) {
        // Releases an ad resource when it fails to load
        ad.dispose();
        print('Ad load failed (code=${error.code} message=${error.message})');
      },
    ),
  ).load();
}
  1. Измените метод build() , чтобы отображать рекламный баннер, когда он доступен.
  2. Обновите itemCount, чтобы подсчитать запись рекламного баннера, и обновите itemBuilder, чтобы отображать баннерную рекламу по индексу объявления ( _kAdIndex ), когда реклама загружается.
  3. Обновите код, чтобы использовать метод _getDestinationItemIndex() для получения индекса элемента контента.

баннер_inline_page.dart

@override
Widget build(BuildContext context) {
  return Scaffold(
    ...
    body: ListView.builder(
      // TODO: Adjust itemCount based on the ad load state
      itemCount: widget.entries.length + (_ad != null ? 1 : 0),
      itemBuilder: (context, index) {
        // TODO: Render a banner ad
        if (_ad != null && index == _kAdIndex) {
          return Container(
            width: _ad!.size.width.toDouble(),
            height: 72.0,
            alignment: Alignment.center,
            child: AdWidget(ad: _ad!),
          );
        } else {
          // TODO: Get adjusted item index from _getDestinationItemIndex()
          final item = widget.entries[_getDestinationItemIndex(index)];

          return ListTile(
            ...
          );
        }
      },
    ),
  );
}
  1. Освободите ресурс, связанный с объектом BannerAd , вызвав метод BannerAd.dispose() в методе обратного вызова dispose() .

баннер_inline_page.dart

@override
void dispose() {
  // TODO: Dispose a BannerAd object
  _ad?.dispose();

  super.dispose();
}

Вот и все! Запустите проект и нажмите кнопку «Баннерное объявление» на главной странице. После загрузки объявления вы увидите рекламный баннер в середине списка.

a5f857a850539fe9.pngc32af50872514224.png

8. Добавьте нативную рекламу

В этом разделе вы отображаете нативное объявление в середине списка, как показано на следующем снимке экрана.

f1671b0fa349ccf8.png

Нативная реклама отображается пользователям с помощью компонентов пользовательского интерфейса, встроенных в платформу (например, View на Android или UIView на iOS).

Однако невозможно создавать собственные компоненты пользовательского интерфейса напрямую с помощью виджетов Flutter. Таким образом, вам необходимо реализовать NativeAdFactory для каждой платформы, который используется для создания представления собственной рекламы для конкретной платформы ( NativeAdView на Android и GADNativeAdView на iOS) из нативного объекта рекламы ( NativeAd на Android и GADNativeAd на iOS).

Реализация NativeAdFactory для Android (Java)

  1. Откройте файл android/build.gradle (или любой файл в папке Android ) и нажмите «Открыть для редактирования в Android Studio», чтобы открыть проект Android.

623ad3d2282ccbf8.png

  1. Если вас попросят выбрать окно для открытия нового проекта, нажмите «Новое окно» , чтобы проект Flutter оставался открытым, пока вы работаете над проектом Android.

d188bb51cf7c2d08.png

Создайте собственный макет объявления

  1. Открыв проект Android, щелкните правой кнопкой мыши приложение на панели проекта в Android Studio и выберите «Создать» > «Файл ресурсов Android» в контекстном меню.

2b629ee277a68fd7.png

  1. В диалоговом окне «Новый файл ресурсов» введите list_tile_native_ad.xml в качестве имени файла.
  2. Выберите «Макет» в качестве типа ресурса и введите com.google.android.gms.ads.nativead.NativeAdView в качестве корневого элемента.
  3. Нажмите «ОК» , чтобы создать новый файл макета.

575f126dd018bc0.png

  1. Реализуйте макет объявления следующим образом. Обратите внимание, что макет должен соответствовать визуальному оформлению пользовательского интерфейса платформы, для которой он предназначен.

list_tile_native_ad.xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/tv_list_tile_native_ad_attribution_small"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#F19938"
            android:text="Ad"
            android:textColor="#FFFFFF"
            android:textSize="12sp" />

        <ImageView
            android:id="@+id/iv_list_tile_native_ad_icon"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:scaleType="fitXY"
            tools:background="#EDEDED" />

        <TextView
            android:id="@+id/tv_list_tile_native_ad_attribution_large"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:background="#F19938"
            android:gravity="center"
            android:text="Ad"
            android:textColor="#FFFFFF"
            android:visibility="invisible" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="80dp"
            android:layout_marginLeft="80dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_list_tile_native_ad_headline"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:lines="1"
                android:maxLines="1"
                android:textColor="#000000"
                android:textSize="16sp"
                tools:text="Headline" />

            <TextView
                android:id="@+id/tv_list_tile_native_ad_body"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:lines="1"
                android:maxLines="1"
                android:textColor="#828282"
                android:textSize="14sp"
                tools:text="body" />

        </LinearLayout>

    </FrameLayout>

</com.google.android.gms.ads.nativead.NativeAdView>

Создайте класс ListTileNativeAdFactory.

  1. На панели «Проект» щелкните правой кнопкой мыши пакет com.codelab.flutter.admobinlineads и выберите «Создать» > «Класс Java» .

9f3f111dd207a9b4.png

  1. Введите ListTileNativeAdFactory в качестве имени и выберите Class из списка.

47ff82d92676e26.png

  1. После появления диалогового окна «Новый класс» оставьте все пустым и нажмите «ОК» .

Вы увидите, что класс ListTileNativeAdFactory создан в пакете com.codelab.flutter.admobinlineads .

e4ed232c358ffb19.png

  1. Реализуйте класс ListTileNativeAdFactory следующим образом. Обратите внимание, что класс реализует метод createNativeAd() в интерфейсе GoogleMobileAdsPlugin.NativeAdFactory .

Фабричный класс отвечает за создание объекта представления для отображения нативного объявления. Как видно из кода, фабричный класс создает UnifiedNativeAdView и заполняет его объектом NativeAd .

ListTileNativeAdFactory.java

// TODO: Implement ListTileNativeAdFactory class

package com.codelab.flutter.admobinlineads;

import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.Map;

import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin;

class ListTileNativeAdFactory implements GoogleMobileAdsPlugin.NativeAdFactory {

    private final Context context;

    ListTileNativeAdFactory(Context context) {
        this.context = context;
    }

    @Override
    public NativeAdView createNativeAd(
            NativeAd nativeAd, Map<String, Object> customOptions) {
        NativeAdView nativeAdView = (NativeAdView) LayoutInflater.from(context)
                .inflate(R.layout.list_tile_native_ad, null);

        TextView attributionViewSmall = nativeAdView
                .findViewById(R.id.tv_list_tile_native_ad_attribution_small);
        TextView attributionViewLarge = nativeAdView
                .findViewById(R.id.tv_list_tile_native_ad_attribution_large);

        ImageView iconView = nativeAdView.findViewById(R.id.iv_list_tile_native_ad_icon);
        NativeAd.Image icon = nativeAd.getIcon();
        if (icon != null) {
            attributionViewSmall.setVisibility(View.VISIBLE);
            attributionViewLarge.setVisibility(View.INVISIBLE);
            iconView.setImageDrawable(icon.getDrawable());
        } else {
            attributionViewSmall.setVisibility(View.INVISIBLE);
            attributionViewLarge.setVisibility(View.VISIBLE);
        }
        nativeAdView.setIconView(iconView);

        TextView headlineView = nativeAdView.findViewById(R.id.tv_list_tile_native_ad_headline);
        headlineView.setText(nativeAd.getHeadline());
        nativeAdView.setHeadlineView(headlineView);

        TextView bodyView = nativeAdView.findViewById(R.id.tv_list_tile_native_ad_body);
        bodyView.setText(nativeAd.getBody());
        bodyView.setVisibility(nativeAd.getBody() != null ? View.VISIBLE : View.INVISIBLE);
        nativeAdView.setBodyView(bodyView);

        nativeAdView.setNativeAd(nativeAd);

        return nativeAdView;
    }
}

Зарегистрируйте класс ListTileNativeAdFactory.

Экземпляр NativeAdFactory должен быть зарегистрирован в GoogleMobileAdsPlugin прежде чем его можно будет использовать со стороны Flutter.

  1. Откройте файл MainActivity.java и переопределите методы configureFlutterEngine() и cleanUpFlutterEngine() .
  2. Зарегистрируйте класс ListTileNativeAdFactory с уникальным идентификатором строки ( listTile ) в методе configureFlutterEngine() .

MainActivity.java

public class MainActivity extends FlutterActivity {

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);

        // TODO: Register the ListTileNativeAdFactory
        GoogleMobileAdsPlugin.registerNativeAdFactory(flutterEngine, "listTile",
                new ListTileNativeAdFactory(getContext()));
    }

    ...
}
  1. Во время процесса очистки необходимо отменить регистрацию каждого экземпляра NativeAdFactory . Отмените регистрацию класса ListTileNativeAdFactory в методе cleanUpFlutterEngine() .

MainActivity.java

public class MainActivity extends FlutterActivity {

    ...

    @Override
    public void cleanUpFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.cleanUpFlutterEngine(flutterEngine);

        // TODO: Unregister the ListTileNativeAdFactory
        GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "listTile");
    }
}

Теперь вы готовы использовать класс ListTileNativeAdFactory для отображения нативной рекламы на Android.

Реализация NativeAdFactory для Android (Kotlin)

  1. Откройте файл android/build.gradle (или любой файл в папке Android ) и нажмите «Открыть для редактирования в Android Studio», чтобы открыть проект Android.

623ad3d2282ccbf8.png

  1. Если вас попросят выбрать окно для открытия нового проекта, нажмите «Новое окно» , чтобы проект Flutter оставался открытым, пока вы работаете над проектом Android.

d188bb51cf7c2d08.png

Создайте собственный макет объявления

  1. Открыв проект Android, щелкните правой кнопкой мыши приложение на панели проекта в Android Studio и выберите «Создать» > «Файл ресурсов Android» в контекстном меню.

2b629ee277a68fd7.png

  1. В диалоговом окне «Новый файл ресурсов» введите list_tile_native_ad.xml в качестве имени файла.
  2. Выберите «Макет» в качестве типа ресурса и введите com.google.android.gms.ads.nativead.NativeAdView в качестве корневого элемента.
  3. Нажмите «ОК» , чтобы создать новый файл макета.

575f126dd018bc0.png

  1. Реализуйте макет объявления следующим образом. Обратите внимание, что макет должен соответствовать визуальному оформлению пользовательского интерфейса платформы, для которой он предназначен.

list_tile_native_ad.xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/tv_list_tile_native_ad_attribution_small"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#F19938"
            android:text="Ad"
            android:textColor="#FFFFFF"
            android:textSize="12sp" />

        <ImageView
            android:id="@+id/iv_list_tile_native_ad_icon"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:scaleType="fitXY"
            tools:background="#EDEDED" />

        <TextView
            android:id="@+id/tv_list_tile_native_ad_attribution_large"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:background="#F19938"
            android:gravity="center"
            android:text="Ad"
            android:textColor="#FFFFFF"
            android:visibility="invisible" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="80dp"
            android:layout_marginLeft="80dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_list_tile_native_ad_headline"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:lines="1"
                android:maxLines="1"
                android:textColor="#000000"
                android:textSize="16sp"
                tools:text="Headline" />

            <TextView
                android:id="@+id/tv_list_tile_native_ad_body"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:lines="1"
                android:maxLines="1"
                android:textColor="#828282"
                android:textSize="14sp"
                tools:text="body" />

        </LinearLayout>

    </FrameLayout>

</com.google.android.gms.ads.nativead.NativeAdView>

Создайте класс ListTileNativeAdFactory.

  1. На панели «Проект» щелкните правой кнопкой мыши пакет com.codelab.flutter.admobinlineads и выберите «Создать» > «Файл/класс Kotlin» .

7311744cb97cad75.png

  1. Введите ListTileNativeAdFactory в качестве имени и выберите Class из списка.

25691151b5814867.png

  1. Вы увидите, что класс ListTileNativeAdFactory создан в пакете com.codelab.flutter.admobinlineads .
  2. Реализуйте класс ListTileNativeAdFactory следующим образом. Обратите внимание, что класс реализует метод createNativeAd() в интерфейсе GoogleMobileAdsPlugin.NativeAdFactory .

Фабричный класс отвечает за создание объекта представления для отображения нативного объявления. Как видно из кода, фабричный класс создает NativeAdView и заполняет его объектом NativeAd .

ListTileNativeAdFactory.kt

// TODO: Implement ListTileNativeAdFactory class

package com.codelab.flutter.admobinlineads

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.gms.ads.nativead.NativeAdView
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin

class ListTileNativeAdFactory(val context: Context) : GoogleMobileAdsPlugin.NativeAdFactory {

    override fun createNativeAd(
            nativeAd: NativeAd,
            customOptions: MutableMap<String, Any>?
    ): NativeAdView {
        val nativeAdView = LayoutInflater.from(context)
                .inflate(R.layout.list_tile_native_ad, null) as NativeAdView

        with(nativeAdView) {
            val attributionViewSmall =
                    findViewById<TextView>(R.id.tv_list_tile_native_ad_attribution_small)
            val attributionViewLarge =
                    findViewById<TextView>(R.id.tv_list_tile_native_ad_attribution_large)

            val iconView = findViewById<ImageView>(R.id.iv_list_tile_native_ad_icon)
            val icon = nativeAd.icon
            if (icon != null) {
                attributionViewSmall.visibility = View.VISIBLE
                attributionViewLarge.visibility = View.INVISIBLE
                iconView.setImageDrawable(icon.drawable)
            } else {
                attributionViewSmall.visibility = View.INVISIBLE
                attributionViewLarge.visibility = View.VISIBLE
            }
            this.iconView = iconView

            val headlineView = findViewById<TextView>(R.id.tv_list_tile_native_ad_headline)
            headlineView.text = nativeAd.headline
            this.headlineView = headlineView

            val bodyView = findViewById<TextView>(R.id.tv_list_tile_native_ad_body)
            with(bodyView) {
                text = nativeAd.body
                visibility = if (nativeAd.body.isNotEmpty()) View.VISIBLE else View.INVISIBLE
            }
            this.bodyView = bodyView

            setNativeAd(nativeAd)
        }

        return nativeAdView
    }
}

Зарегистрируйте класс ListTileNativeAdFactory.

Экземпляр NativeAdFactory должен быть зарегистрирован в GoogleMobileAdsPlugin прежде чем его можно будет использовать со стороны Flutter.

  1. Откройте файл MainActivity.kt и переопределите методы configureFlutterEngine() и cleanUpFlutterEngine() .
  2. Зарегистрируйте класс ListTileNativeAdFactory с уникальным идентификатором строки ( listTile ) в методе configureFlutterEngine() .

MainActivity.kt

class MainActivity: FlutterActivity() {

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        // TODO: Register the ListTileNativeAdFactory
        GoogleMobileAdsPlugin.registerNativeAdFactory(
                flutterEngine, "listTile", ListTileNativeAdFactory(context))
    }

    ...
}
  1. Во время процесса очистки необходимо отменить регистрацию каждого экземпляра NativeAdFactory . Отмените регистрацию класса ListTileNativeAdFactory в методе cleanUpFlutterEngine() .

MainActivity.kt

class MainActivity: FlutterActivity() {
    ...

    override fun cleanUpFlutterEngine(flutterEngine: FlutterEngine) {
        super.cleanUpFlutterEngine(flutterEngine)

        // TODO: Unregister the ListTileNativeAdFactory
        GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "listTile")
    }
}

Теперь вы готовы использовать класс ListTileNativeAdFactory для отображения нативной рекламы на Android.

Реализация NativeAdFactory для iOS (Objective-C)

Откройте файл ios/Podfile (или любой файл в папке ios ) и нажмите «Открыть модуль iOS в Xcode», чтобы открыть проект iOS.

62aa12c10e6d671f.png

Подготовьте макет нативного объявления

Вам понадобится собственное представление ( *.xib ) для размещения собственных рекламных ресурсов. В этой лаборатории кода используется предварительно настроенное представление, чтобы свести к минимуму ваши усилия.

Открыв проект iOS в Xcode, убедитесь, что ListTileNativeAdView.xib существует в проекте Runner .

a5f04a32f1868d4f.png

Создайте класс ListTileNativeAdFactory.

  1. From the project navigator, right-click the Runner group, and select New File to create a header file for the new class.

6455aab9e9881ca.png

  1. В диалоговом окне шаблона выберите файл заголовка и назовите его ListTileNativeAdFactory .
  2. После создания файла ListTileNativeAdFactory.h определите класс ListNativeAdFactory следующим образом:

ListTileNativeAdFactory.h

#ifndef ListTileNativeAdFactory_h
#define ListTileNativeAdFactory_h

// TODO: Import FLTGoogleMobileAdsPlugin.h
#import "FLTGoogleMobileAdsPlugin.h"

// TODO: Declare ListTileNativeAdFactory
@interface ListTileNativeAdFactory : NSObject<FLTNativeAdFactory>

@end


#endif /* ListTileNativeAdFactory_h */
  1. Создайте файл Objective-C, выбрав «Новый файл» в группе «Выполнитель» .
  2. В следующем диалоговом окне введите ListTileNativeAdFactory в поле «Файл» и выберите «Пустой файл» в качестве типа файла.

2c9c998c48db3a0.png

  1. После того, как вы нажмете «Далее» , вам будет предложено выбрать папку, в которой должен быть создан новый файл. Оставьте все без изменений и нажмите «Создать» .

8635ffe502d1f4ab.png

  1. Реализуйте класс ListTileNativeFactory следующим образом. Обратите внимание, что класс реализует метод createNativeAd() в протоколе FLTNativeAdFactory .

Фабричный класс отвечает за создание объекта представления для отображения нативного объявления. Как видно из кода, фабричный класс создает GADNativeAdView и заполняет его объектом GADNativeAd .

ListTileNativeAdFactory.m

// TODO: Import ListTileNativeAdFactory.h
#import "ListTileNativeAdFactory.h"

// TODO: Implement ListTileNativeAdFactory
@implementation ListTileNativeAdFactory

- (GADNativeAdView *)createNativeAd:(GADNativeAd *)nativeAd
                             customOptions:(NSDictionary *)customOptions {
  GADNativeAdView *nativeAdView =
    [[NSBundle mainBundle] loadNibNamed:@"ListTileNativeAdView" owner:nil options:nil].firstObject;

  ((UILabel *)nativeAdView.headlineView).text = nativeAd.headline;

  ((UILabel *)nativeAdView.bodyView).text = nativeAd.body;
  nativeAdView.bodyView.hidden = nativeAd.body ? NO : YES;

  ((UIImageView *)nativeAdView.iconView).image = nativeAd.icon.image;
  nativeAdView.iconView.hidden = nativeAd.icon ? NO : YES;

  nativeAdView.callToActionView.userInteractionEnabled = NO;

  nativeAdView.nativeAd = nativeAd;

  return nativeAdView;
}

@end

Зарегистрируйте класс ListTileNativeAdFacotry.

Реализация FLTNativeAdFactory должна быть зарегистрирована в FLTGoogleMobileAdsPlugin прежде чем ее можно будет использовать со стороны Flutter.

Откройте файл AppDelegate.m и зарегистрируйте ListTileNativeAdFactory с уникальным идентификатором строки ( listTile ), вызвав метод [FLTGoogleMobileAdsPlugin registerNativeAdFactory] .

AppDelegate.m

#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"

// TODO: Import ListTileNativeAdFactory.h
#import "ListTileNativeAdFactory.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];

  // TODO: Register ListTileNativeAdFactory
  ListTileNativeAdFactory *listTileFactory = [[ListTileNativeAdFactory alloc] init];
  [FLTGoogleMobileAdsPlugin registerNativeAdFactory:self
                                        factoryId:@"listTile"
                                  nativeAdFactory:listTileFactory];

  // Override point for customization after application launch.
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end

Теперь вы готовы использовать ListTileNativeAdFactory для отображения нативной рекламы на iOS.

Реализация NativeAdFactory для iOS (Swift)

Откройте файл ios/Podfile (или любой файл в папке ios ) и нажмите «Открыть модуль iOS в Xcode», чтобы открыть проект iOS.

62aa12c10e6d671f.png

Подготовьте макет нативного объявления

Вам понадобится собственное представление ( *.xib ) для размещения собственных рекламных ресурсов. В этой лаборатории предварительно настроенное представление используется для минимизации ваших усилий.

Открыв проект iOS в Xcode, убедитесь, что ListTileNativeAdView.xib существует в проекте Runner .

a5f04a32f1868d4f.png

Создайте класс ListTileNativeAdFactory.

  1. В навигаторе проекта щелкните правой кнопкой мыши группу Runner и выберите «Новый файл» , чтобы создать файл заголовка для нового класса.

9115c92543345ef1.png

  1. В диалоговом окне шаблона выберите Swift File и назовите его ListTileNativeAdFactory .
  2. После создания файла ListTileNativeAdFactory.swift реализуйте класс ListNativeAdFactory .

Обратите внимание, что класс реализует метод createNativeAd() в протоколе FLTNativeAdFactory .

Фабричный класс отвечает за создание объекта представления для отображения нативного объявления. Как видно из кода, фабричный класс создает GADNativeAdView и заполняет его объектом GADNativeAd .

ListTileNativeAdFactory.swift

// TODO: Import google_mobile_ads
import google_mobile_ads

// TODO: Implement ListTileNativeAdFactory
class ListTileNativeAdFactory : FLTNativeAdFactory {

    func createNativeAd(_ nativeAd: GADNativeAd,
                        customOptions: [AnyHashable : Any]? = nil) -> GADNativeAdView? {
        let nibView = Bundle.main.loadNibNamed("ListTileNativeAdView", owner: nil, options: nil)!.first
        let nativeAdView = nibView as! GADNativeAdView

        (nativeAdView.headlineView as! UILabel).text = nativeAd.headline

        (nativeAdView.bodyView as! UILabel).text = nativeAd.body
        nativeAdView.bodyView!.isHidden = nativeAd.body == nil

        (nativeAdView.iconView as! UIImageView).image = nativeAd.icon?.image
        nativeAdView.iconView!.isHidden = nativeAd.icon == nil

        nativeAdView.callToActionView?.isUserInteractionEnabled = false

        nativeAdView.nativeAd = nativeAd

        return nativeAdView
    }
}

Зарегистрируйте класс ListTileNativeAdFacotry.

Реализация FLTNativeAdFactory должна быть зарегистрирована в FLTGoogleMobileAdsPlugin прежде чем ее можно будет использовать со стороны Flutter.

Откройте файл AppDelegate.m и зарегистрируйте ListTileNativeAdFactory с уникальным идентификатором строки ( listTile ), вызвав метод FLTGoogleMobileAdsPlugin.registerNativeAdFactory() .

AppDelegate.swift

import UIKit
import Flutter

// TODO: Import google_mobile_ads
import google_mobile_ads

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)

    // TODO: Register ListTileNativeAdFactory
    let listTileFactory = ListTileNativeAdFactory()
    FLTGoogleMobileAdsPlugin.registerNativeAdFactory(
        self, factoryId: "listTile", nativeAdFactory: listTileFactory)

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

Теперь вы готовы использовать ListTileNativeAdFactory для отображения нативной рекламы на iOS.

Интегрируйте нативную рекламу с виджетами Flutter.

  1. Откройте файл lib/native_inline_page.dart . Затем импортируйте ad_helper.dart и google_mobile_ads.dart , добавив следующие строки:

native_inline_page.dart

...

// TODO: Import ad_helper.dart
import 'package:admob_inline_ads_in_flutter/ad_helper.dart';

// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';

class NativeInlinePage extends StatefulWidget {
  ...
}
  1. В класс _NativeInlinePageState добавьте следующие члены и методы для нативного объявления.

Обратите внимание, что _kAdIndex указывает индекс, в котором будет отображаться рекламный баннер, и используется для расчета индекса элемента с помощью метода _getDestinationItemIndex() .

native_inline_page.dart

class _NativeInlinePageState extends State<NativeInlinePage> {

  // TODO: Add _kAdIndex
  static final _kAdIndex = 4;

  // TODO: Add a native ad instance
  NativeAd? _ad;

  ...

  // TODO: Add _getDestinationItemIndex()
  int _getDestinationItemIndex(int rawIndex) {
    if (rawIndex >= _kAdIndex && _ad != null) {
      return rawIndex - 1;
    }
    return rawIndex;
  }

  ...
}
  1. В методе initState() создайте и загрузите NativeAd , который использует ListTileNativeAdFactory для создания собственного представления рекламы.

Обратите внимание, что используется тот же идентификатор фабрики ( listTile ), который использовался для регистрации фабрики в плагине.

native_inline_page.dart

@override
void initState() {
  super.initState();

  // TODO: Create a NativeAd instance
  _ad = NativeAd(
    adUnitId: AdHelper.nativeAdUnitId,
    factoryId: 'listTile',
    request: AdRequest(),
    listener: NativeAdListener(
      onAdLoaded: (ad) {
        setState(() {
          _ad = ad as NativeAd;
        });
      },
      onAdFailedToLoad: (ad, error) {
        // Releases an ad resource when it fails to load
        ad.dispose();
        print('Ad load failed (code=${error.code} message=${error.message})');       },
    ),
  );

  _ad.load();
}
  1. Измените метод build() , чтобы отображать рекламный баннер, когда он доступен.
  2. Обновите itemCount, чтобы подсчитать запись рекламного баннера, и обновите itemBuilder, чтобы отображать баннерную рекламу по индексу объявления ( _kAdIndex ), когда реклама загружается.
  3. Обновите код, чтобы использовать метод _getDestinationItemIndex() для получения индекса элемента контента.

native_inline_page.dart

@override
Widget build(BuildContext context) {
  return Scaffold(
    ...
    body: ListView.builder(
      // TODO: Adjust itemCount based on the ad load state
      itemCount: widget.entries.length + (_ad != null ? 1 : 0),
      itemBuilder: (context, index) {
        // TODO: Render a banner ad
        if (_ad != null && index == _kAdIndex) {
          return Container(
            height: 72.0,
            alignment: Alignment.center,
            child: AdWidget(ad: _ad!),
          );
        } else {
          // TODO: Get adjusted item index from _getDestinationItemIndex()
          final item = widget.entries[_getDestinationItemIndex(index)];

          return ListTile(
            ...
          );
        }
      },
    ),
  );
}
  1. Освободите ресурс, связанный с объектом NativeAd , вызвав метод NativeAd.dispose() в методе обратного вызова dispose() .

native_inline_page.dart

@override
void dispose() {
  // TODO: Dispose a NativeAd object
  _ad?.dispose();

  super.dispose();
}

Вот и все! Запустите проект и нажмите кнопку «Нативное встроенное объявление» на главной странице. После загрузки объявления вы увидите нативное объявление в середине списка.

f1671b0fa349ccf8.png5ead873222c800eb.png

9. Все готово!

Вы завершили кодовую лабораторию. Вы можете найти готовый код для этой лаборатории кода в разделе android_studio_folder.png полный или android_studio_folder.png папка Complete_kotlin_swift .