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
Репозиторий содержит три папки:
Задание: Начальный код, который вы будете создавать в этом практическом занятии.
Завершено: Код для данной практической работы готов. (Java и Objective-C для нативного кода)
complete_kotlin_swift: Завершенный код для этого практического занятия. (Kotlin и Swift для нативного кода)
3. Настройте приложение AdMob и рекламные блоки.
Поскольку Flutter — это многоплатформенный SDK, вам необходимо добавить приложение и рекламные блоки как для Android, так и для iOS в AdMob.
Настройка для Android
Для настройки под Android необходимо добавить приложение Android и создать рекламные блоки.
Добавить приложение для Android
- В консоли AdMob нажмите кнопку «ДОБАВИТЬ ПРИЛОЖЕНИЕ» в меню «Приложения» .
- Когда вас спросят: «Вы опубликовали свое приложение в Google Play или App Store?» , нажмите «НЕТ» .
- В поле «Название приложения» введите
AdMob inline adsи выберите Android в качестве платформы.

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

Создавайте рекламные блоки
Чтобы добавить рекламные блоки:
- В консоли AdMob выберите приложение «Встроенная реклама AdMob» в меню « Приложения ».
- Нажмите на меню «Рекламные блоки» .
Баннер
|
|
Родной
|
|
Обычно для показа нового рекламного блока требуется несколько часов.
Если вы хотите немедленно проверить работу рекламы, используйте идентификаторы тестового приложения и рекламного блока, указанные в таблицах идентификаторов приложений/рекламных блоков для Android и iOS.
Настройка для iOS
Для настройки под iOS необходимо добавить iOS-приложение и создать рекламные блоки.
Добавить приложение для iOS
- В консоли AdMob нажмите кнопку «ДОБАВИТЬ ПРИЛОЖЕНИЕ» в меню «Приложения» .
- Когда вас спросят: «Вы опубликовали свое приложение в Google Play или App Store?» , нажмите «НЕТ» .
- В поле «Название приложения» введите
AdMob inline adsи выберите iOS в качестве платформы.

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

Создавайте рекламные блоки
Чтобы добавить рекламные блоки:
- В консоли AdMob выберите приложение «Встроенная реклама AdMob» в меню « Приложения ».
- Нажмите на меню «Рекламные блоки» .
Баннер
|
|
Родной
|
|
Обычно для показа нового рекламного блока требуется несколько часов.
Если вы хотите немедленно проверить работу рекламы, используйте идентификаторы тестового приложения и рекламного блока, указанные в следующей таблице.
Дополнительно: воспользуйтесь тестовым приложением AdMob и рекламными блоками.
Если вы хотите следовать инструкциям из практического руководства, вместо того чтобы создавать новое приложение и рекламные блоки самостоятельно, вы можете использовать идентификаторы тестового приложения AdMob и идентификаторы рекламных блоков, указанные в следующих таблицах.
Идентификатор приложения Android/идентификатор рекламного блока
Элемент | Идентификатор приложения/идентификатор рекламного блока |
Идентификатор приложения AdMob | |
Баннер | |
Родной | |
Идентификатор приложения iOS/идентификатор рекламного блока
Элемент | Идентификатор приложения/идентификатор рекламного блока |
Идентификатор приложения AdMob | |
Баннер | |
Родной | |
Для получения дополнительной информации о тестовой рекламе см. документацию для разработчиков по тестовой рекламе для 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 .

Обновите файл AndroidManifest.xml (Android)
- Откройте файл
android/app/src/main/AndroidManifest.xmlв Android Studio. - Добавьте идентификатор вашего приложения 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)
- Откройте файл
ios/Runner/Info.plistв Android Studio. - Добавьте ключ
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
Перед загрузкой рекламы необходимо инициализировать SDK Google Mobile Ads. Откройте файл lib/home_page.dart и измените функцию _initGoogleMobileAds() , чтобы инициализировать SDK до загрузки главной страницы.
Обратите внимание, что для получения результата инициализации SDK после её завершения необходимо изменить тип возвращаемого значения метода _initGoogleMobileAds() с Future<dynamic> на Future<InitializationStatus> .
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. Добавьте баннерную рекламу.
В этом разделе вы размещаете баннерную рекламу в середине списка, как показано на следующем скриншоте.

- Откройте файл
lib/banner_inline_page.dart. - Для импорта
ad_helper.dartиgoogle_mobile_ads.dartдобавьте следующие строки:
banner_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 BannerInlinePage extends StatefulWidget {
...
}
- В класс
_BannerInlinePageStateдобавьте следующие члены и методы для баннерной рекламы.
Обратите внимание, что _kAdIndex указывает индекс, по которому будет отображаться баннерная реклама, и используется для вычисления индекса элемента в методе _getDestinationItemIndex() .
banner_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;
}
...
}
- В методе
initState()создайте и загрузитеBannerAdразмером 320x50 пикселей (AdSize.banner). Обратите внимание, что обработчик событий рекламы настроен на обновление пользовательского интерфейса (setState()) при загрузке рекламы.
banner_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();
}
- Измените метод
build()таким образом, чтобы при наличии баннерной рекламы отображалась соответствующая реклама. - Обновите
itemCount,чтобы он подсчитывал количество показов баннерной рекламы, и обновитеitemBuilder,чтобы он отображал баннерную рекламу по индексу объявления (_kAdIndex) при загрузке объявления. - Обновите код, чтобы использовать метод
_getDestinationItemIndex()для получения индекса элемента контента.
banner_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(
...
);
}
},
),
);
}
- Освободите ресурс, связанный с объектом
BannerAd, вызвав методBannerAd.dispose()в методе обратного вызоваdispose().
banner_inline_page.dart
@override
void dispose() {
// TODO: Dispose a BannerAd object
_ad?.dispose();
super.dispose();
}
Вот и всё! Запустите проект и нажмите кнопку «Встроенная баннерная реклама» на главной странице. После загрузки рекламы вы увидите баннерную рекламу в середине списка.


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

Нативная реклама отображается пользователям с использованием компонентов пользовательского интерфейса, которые являются собственными для платформы (например, View на Android или UIView на iOS).
Однако создавать нативные компоненты пользовательского интерфейса напрямую с помощью виджетов Flutter невозможно. Поэтому для каждой платформы необходимо реализовать NativeAdFactory , который используется для создания специфичного для платформы представления нативной рекламы ( NativeAdView на Android и GADNativeAdView на iOS) из объекта нативной рекламы ( NativeAd на Android и GADNativeAd на iOS).
Реализация NativeAdFactory для Android (Java)
- Откройте файл
android/build.gradle(или любой другой файл в папке android ) и нажмите «Открыть для редактирования» в Android Studio , чтобы открыть проект Android.

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

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

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

- Разместите рекламное объявление следующим образом. Обратите внимание, что макет должен соответствовать визуальному оформлению пользовательского интерфейса платформы, для которой оно предназначено.
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.
- В панели «Проект» щелкните правой кнопкой мыши пакет com.codelab.flutter.admobinlineads и выберите «Создать» > «Класс Java» .

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

- После появления диалогового окна «Новый класс» оставьте все поля пустыми и нажмите «ОК» .
Вы увидите, что класс ListTileNativeAdFactory создан в пакете com.codelab.flutter.admobinlineads .

- Реализуйте класс
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 на стороне Flutter его необходимо зарегистрировать в плагине GoogleMobileAdsPlugin .
- Откройте файл
MainActivity.javaи переопределите методыconfigureFlutterEngine()иcleanUpFlutterEngine(). - Зарегистрируйте класс
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()));
}
...
}
- В процессе очистки необходимо отменить регистрацию каждого экземпляра
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)
- Откройте файл
android/build.gradle(или любой другой файл в папке android ) и нажмите «Открыть для редактирования» в Android Studio , чтобы открыть проект Android.

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

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

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

- Разместите рекламное объявление следующим образом. Обратите внимание, что макет должен соответствовать визуальному оформлению пользовательского интерфейса платформы, для которой оно предназначено.
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.
- В панели «Проект» щелкните правой кнопкой мыши пакет com.codelab.flutter.admobinlineads и выберите «Создать» > «Файл/класс Kotlin» .

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

- Вы увидите, что класс
ListTileNativeAdFactoryсоздан в пакетеcom.codelab.flutter.admobinlineads. - Реализуйте класс
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 на стороне Flutter его необходимо зарегистрировать в плагине GoogleMobileAdsPlugin .
- Откройте файл
MainActivity.ktи переопределите методыconfigureFlutterEngine()иcleanUpFlutterEngine(). - Зарегистрируйте класс
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))
}
...
}
- В процессе очистки необходимо отменить регистрацию каждого экземпляра
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.

Подготовьте макет нативной рекламы.
Для размещения рекламных материалов вам потребуется собственный шаблон представления ( *.xib ). В этом практическом задании используется предварительно настроенный шаблон представления, чтобы свести ваши усилия к минимуму.
Откройте проект iOS в Xcode и убедитесь, что файл ListTileNativeAdView.xib существует в проекте Runner .

Создайте класс ListTileNativeAdFactory.
- В навигаторе проекта щелкните правой кнопкой мыши группу Runner и выберите New File , чтобы создать заголовочный файл для нового класса.

- В диалоговом окне шаблона выберите файл заголовка и назовите его
ListTileNativeAdFactory. - После создания файла
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 */
- Создайте файл Objective-C, выбрав «Новый файл» в группе «Выполняющие команды» .
- В следующем диалоговом окне введите
ListTileNativeAdFactoryв поле «Файл» и выберите «Пустой файл» в качестве типа файла.

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

- Реализуйте класс
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
Зарегистрируйте класс ListTileNativeAdFacortry
Для использования реализации FLTNativeAdFactory на стороне Flutter её необходимо зарегистрировать в FLTGoogleMobileAdsPlugin .
Откройте файл 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.

Подготовьте макет нативной рекламы.
Для размещения рекламных материалов вам потребуется собственный шаблон представления ( *.xib ). В этом практическом задании используется предварительно настроенный шаблон представления, чтобы свести ваши усилия к минимуму.
Откройте проект iOS в Xcode и убедитесь, что файл ListTileNativeAdView.xib существует в проекте Runner .

Создайте класс ListTileNativeAdFactory.
- В навигаторе проекта щелкните правой кнопкой мыши группу Runner и выберите New File , чтобы создать заголовочный файл для нового класса.

- В диалоговом окне шаблона выберите файл Swift и назовите его
ListTileNativeAdFactory. - После создания файла
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
}
}
Зарегистрируйте класс ListTileNativeAdFacortry
Для использования реализации FLTNativeAdFactory на стороне Flutter её необходимо зарегистрировать в FLTGoogleMobileAdsPlugin .
Откройте файл 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.
- Откройте файл
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 {
...
}
- В класс
_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;
}
...
}
- В методе
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();
}
- Измените метод
build()таким образом, чтобы при наличии баннерной рекламы отображалась соответствующая реклама. - Обновите
itemCount,чтобы он подсчитывал количество показов баннерной рекламы, и обновитеitemBuilder,чтобы он отображал баннерную рекламу по индексу объявления (_kAdIndex) при загрузке объявления. - Обновите код, чтобы использовать метод
_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(
...
);
}
},
),
);
}
- Освободите ресурс, связанный с объектом
NativeAd, вызвав методNativeAd.dispose()в методе обратного вызоваdispose().
native_inline_page.dart
@override
void dispose() {
// TODO: Dispose a NativeAd object
_ad?.dispose();
super.dispose();
}
Вот и всё! Запустите проект и нажмите кнопку «Встроенная нативная реклама» на главной странице. После загрузки рекламы вы увидите нативную рекламу в середине списка.


9. Всё готово!
Вы завершили выполнение задания в CodeLab. Полный код для этого задания можно найти в...
полный или
папка complete_kotlin_swift .

