1. 簡介
在本程式碼研究室中,您將在 Flutter 應用程式中導入 AdMob 橫幅廣告和 AdMob 原生內嵌廣告。
建構項目
本程式碼研究室會引導您使用 Flutter 專用的 Google 行動廣告外掛程式,在 Flutter 應用程式中導入 AdMob 內嵌橫幅廣告和 AdMob 原生廣告內嵌廣告。
在執行本程式碼研究室的過程中,如果您遇到任何問題 (例如程式碼錯誤、文法錯誤、用詞不明確等),請使用程式碼研究室左下角的「回報錯誤」連結來回報問題。
課程內容
- 如何設定 Google 行動廣告 Flutter 外掛程式
- 如何在 Flutter 應用程式中導入內嵌橫幅廣告和獎勵廣告
軟硬體需求
- Android Studio 4.1 以上版本
- Xcode 12 以上版本 (適用於 iOS 開發作業)
您對 AdMob 使用體驗的評價如何?
針對使用 Flutter 的經驗,您會給予什麼評價?
2. 設定 Flutter 開發環境
您需要使用兩項軟體:Flutter SDK 和編輯器。
您可以使用下列任一裝置執行程式碼研究室:
- 將實體 Android 或 iOS 裝置接上電腦,並設為開發人員模式。
- iOS 模擬器 (需要安裝 Xcode 工具)。
- Android Emulator (需要在 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,您需要在 AdMob 中新增 Android 和 iOS 的應用程式和廣告單元。
設定 Android 裝置
如要設定 Android,您必須新增 Android 應用程式並建立廣告單元。
新增 Android 應用程式
- 在 AdMob 控制台中,按一下「應用程式」選單中的「新增應用程式」。
- 系統詢問「是否已在 Google Play 或 App Store 發布應用程式?」時,按一下「否」。
- 請在應用程式名稱欄位中輸入
AdMob inline ads
,然後選取「Android」做為平台。
- 完成本程式碼研究室不需要啟用使用者指標。不過我們建議您這麼做,因為可以幫助您深入瞭解使用者行為。按一下「新增」完成程序。
建立廣告單元
新增廣告單元的步驟如下:
- 在 AdMob 管理中心的「應用程式」選單中,選取「AdMob 內嵌廣告」應用程式。
- 按一下「廣告單元」選單。
橫幅廣告
|
原生
|
新的廣告單元通常需要幾個小時才能放送廣告。
如果您想要立即測試廣告行為,請使用 Android 應用程式 ID/廣告單元 ID 和 iOS 應用程式 ID/廣告單元 ID 表格中所列的測試應用程式 ID 和廣告單元 ID。
設定 iOS 裝置
如要設定 iOS,您需要新增 iOS 應用程式並建立廣告單元。
新增 iOS 應用程式
- 在 AdMob 控制台中,按一下「應用程式」選單中的「新增應用程式」。
- 系統詢問「是否已在 Google Play 或 App Store 發布應用程式?」時,按一下「否」。
- 請在應用程式名稱欄位中輸入
AdMob inline ads
,然後選取「iOS」iOS做為平台。
- 完成本程式碼研究室不需要啟用使用者指標。不過我們建議您這麼做,因為可以幫助您深入瞭解使用者行為。按一下「新增」完成程序。
建立廣告單元
新增廣告單元的步驟如下:
- 在 AdMob 管理中心的「應用程式」選單中,選取「AdMob 內嵌廣告」應用程式。
- 按一下「廣告單元」選單。
橫幅廣告
|
原生
|
新的廣告單元通常需要幾個小時才能放送廣告。
如果您想立即測試廣告行為,請使用下表所列的測試應用程式 ID 和廣告單元 ID。
選用:使用測試 AdMob 應用程式和廣告單元
如想按照程式碼研究室的說明操作,而非自行建立新的應用程式和廣告單元,您可以使用下表所列的測試 AdMob 應用程式 ID 和廣告單元 ID。
Android 應用程式 ID/廣告單元 ID
項目 | 應用程式 ID/廣告單元 ID |
AdMob 應用程式 ID |
|
橫幅廣告 |
|
原生 |
|
iOS 應用程式 ID/廣告單元 ID
項目 | 應用程式 ID/廣告單元 ID |
AdMob 應用程式 ID |
|
橫幅廣告 |
|
原生 |
|
如要進一步瞭解測試廣告,請參閱 Android 測試廣告和 iOS 測試廣告開發人員說明文件。
4. 新增 Google Mobile Ads Flutter 外掛程式
Flutter 會透過外掛程式提供不同平台專屬的服務。外掛程式可讓您存取各個平台上的服務和 API。
google_mobile_ads 外掛程式支援使用 AdMob API 載入及顯示橫幅廣告、插頁式廣告、獎勵廣告和原生廣告。
Flutter 是多平台 SDK,因此 google_mobile_ads 外掛程式同時適用於 iOS 和 Android。因此,如果您在 Flutter 應用程式中加入這個外掛程式,Android 和 iOS 版 AdMob 內嵌廣告應用程式都會使用這個外掛程式。
將 Google 行動廣告外掛程式新增為依附元件
如要從 AdMob 內嵌廣告專案存取 AdMob API,請將 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 Studio 中開啟
android/app/src/main/AndroidManifest.xml
檔案。 - 加入名為「
com.google.android.gms.ads.APPLICATION_ID
」的<meta-data>
代碼,加入 AdMob 應用程式 ID。舉例來說,如果您的 AdMob 應用程式 ID 是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)
- 在 Android Studio 中開啟
ios/Runner/Info.plist
檔案。 - 加入包含 AdMob 應用程式 ID 字串值的
GADApplicationIdentifier
鍵。舉例來說,如果您的 AdMob 應用程式 ID 是ca-app-pub-3940256099942544~1458002511
,就必須在Info.plist
檔案中新增下列幾行程式碼。
ios/Runner/Info.plist
...
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-3940256099942544~1458002511</string>
...
5. 新增廣告專用的輔助類別
在 lib
目錄中建立名為 ad_helper.dart
的新檔案。接著,導入 AdHelper
類別,藉此提供 Android 和 iOS 的 AdMob 應用程式 ID 和廣告單元 ID。
請務必將 AdMob 應用程式 ID (ca-app-pub-xxxxxx~yyyyy
) 和廣告單元 ID (ca-app-pub-xxxxxxx/yyyyyyyy
) 替換為您在上一個步驟中建立的 ID。
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 應用程式 ID 和測試廣告單元 ID,請使用下列程式碼片段。
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. 初始化 Google Mobile Ads SDK
載入廣告之前,您需要初始化 Google Mobile Ads SDK。開啟 lib/home_page.dart
檔案並修改 _initGoogleMobileAds()
,在載入首頁前初始化 SDK。
請注意,您需要將 _initGoogleMobileAds()
方法的傳回類型從 Future<dynamic>
變更為 Future<InitializationStatus>
,才能在完成 SDK 初始化結果後取得 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. 新增橫幅廣告
在這個部分中,您將在清單中間顯示橫幅廣告,如下方螢幕截圖所示。
- 開啟
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()
方法中,建立並載入 320x50 橫幅廣告 (AdSize.banner
) 的BannerAd
。請注意,廣告事件監聽器已設為在載入廣告時更新使用者介面 (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(
...
);
}
},
),
);
}
- 在
dispose()
回呼方法中呼叫BannerAd.dispose()
方法,即可釋出與BannerAd
物件相關聯的資源。
banner_inline_page.dart
@override
void dispose() {
// TODO: Dispose a BannerAd object
_ad?.dispose();
super.dispose();
}
大功告成!執行專案,然後按一下首頁的 [橫幅內嵌廣告] 按鈕。廣告載入後,您會在清單中央看到橫幅廣告。
8. 新增原生廣告
在這個部分中,您將在清單中間顯示原生廣告,如下方螢幕截圖所示。
系統會透過平台原生的 UI 元件向使用者顯示原生廣告 (例如 Android 上的 View
或 iOS 上的 UIView
)。
不過,您無法使用 Flutter 小工具直接建立原生 UI 元件。因此,您必須為每個平台導入 NativeAdFactory
,用來從原生廣告物件 (Android 上的「NativeAd
」和 iOS 中的「GADNativeAd
」) 建立特定平台的原生廣告檢視畫面 (Android 上的 NativeAdView
;iOS 上的 GADNativeAdView
)。
導入 Android (Java) 適用的 NativeAdFactory
- 開啟
android/build.gradle
檔案 (或 android 資料夾下的任何檔案),然後按一下「Open to Editing in Android Studio」(在 Android Studio 中開啟,供編輯) 開啟 Android 專案。
- 如果系統要求您選取視窗來開啟新專案,請按一下「New Window」,讓 Flutter 專案在處理 Android 專案時保持開啟狀態。
建立原生廣告版面配置
- 開啟 Android 專案後,在 Android Studio 的專案窗格中的「app」上按一下滑鼠右鍵,然後依序選取「New」>「New」內容選單的 Android 資源檔案。
- 在「New Resource File」對話方塊中,輸入
list_tile_native_ad.xml
做為檔案名稱。 - 選取「Layout」做為資源類型,然後輸入
com.google.android.gms.ads.nativead.NativeAdView
做為根元素。 - 按一下「OK」,建立新的版面配置檔案。
- 實作廣告版面配置,如下所示。請注意,版面配置應符合主要平台的使用者體驗視覺設計。
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」。
- 畫面上出現「New Class」對話方塊後,請將所有項目留空,然後按一下「OK」。
您會看到 ListTileNativeAdFactory
類別已在套件 com.codelab.flutter.admobinlineads
中建立。
- 請按照以下方式實作
ListTileNativeAdFactory
類別。請注意,該類別會在GoogleMobileAdsPlugin.NativeAdFactory
介面中實作createNativeAd()
方法。
工廠類別負責建立用於顯示原生廣告的 View 物件。如程式碼所示,工廠類別會建立 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 端使用。
- 開啟
MainActivity.java
檔案,然後覆寫configureFlutterEngine()
方法和cleanUpFlutterEngine()
方法。 - 在
configureFlutterEngine()
方法中,使用專屬字串 ID (listTile
) 註冊ListTileNativeAdFactory
類別。
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
執行個體。在cleanUpFlutterEngine()
方法中取消註冊ListTileNativeAdFactory
類別。
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 上顯示原生廣告了。
導入 Android 適用的 NativeAdFactory (Kotlin)
- 開啟
android/build.gradle
檔案 (或 android 資料夾下的任何檔案),然後按一下「Open to Editing in Android Studio」(在 Android Studio 中開啟,供編輯) 開啟 Android 專案。
- 如果系統要求您選取視窗來開啟新專案,請按一下「New Window」,讓 Flutter 專案在處理 Android 專案時保持開啟狀態。
建立原生廣告版面配置
- 開啟 Android 專案後,在 Android Studio 的專案窗格中的「app」上按一下滑鼠右鍵,然後依序選取「New」>「New」內容選單的 Android 資源檔案。
- 在「New Resource File」對話方塊中,輸入
list_tile_native_ad.xml
做為檔案名稱。 - 選取「Layout」做為資源類型,然後輸入
com.google.android.gms.ads.nativead.NativeAdView
做為根元素。 - 按一下「OK」,建立新的版面配置檔案。
- 實作廣告版面配置,如下所示。請注意,版面配置應符合主要平台的使用者體驗視覺設計。
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
類別。請注意,該類別會在GoogleMobileAdsPlugin.NativeAdFactory
介面中實作createNativeAd()
方法。
工廠類別負責建立用於顯示原生廣告的 View 物件。如程式碼所示,工廠類別會建立 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 端使用。
- 開啟
MainActivity.kt
檔案,然後覆寫configureFlutterEngine()
方法和cleanUpFlutterEngine()
方法。 - 在
configureFlutterEngine()
方法中,使用專屬字串 ID (listTile
) 註冊ListTileNativeAdFactory
類別。
MainActivity.kt
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
// TODO: Register the ListTileNativeAdFactory
GoogleMobileAdsPlugin.registerNativeAdFactory(
flutterEngine, "listTile", ListTileNativeAdFactory(context))
}
...
}
- 在清理過程中,您應取消註冊每個
NativeAdFactory
執行個體。在cleanUpFlutterEngine()
方法中取消註冊ListTileNativeAdFactory
類別。
MainActivity.kt
class MainActivity: FlutterActivity() {
...
override fun cleanUpFlutterEngine(flutterEngine: FlutterEngine) {
super.cleanUpFlutterEngine(flutterEngine)
// TODO: Unregister the ListTileNativeAdFactory
GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "listTile")
}
}
您現在可以使用 ListTileNativeAdFactory
類別在 Android 上顯示原生廣告了。
導入 NativeAdFactory for iOS (Objective-C)
開啟 ios/Podfile
檔案 (或「ios」資料夾下的任何檔案),然後按一下「在 Xcode 中開啟 iOS 模組」,即可開啟 iOS 專案。
準備原生廣告版面配置
您必須有自訂資料檢視 (*.xib
),才能設定原生廣告素材資源。在本程式碼研究室中,系統會使用預先設定的檢視畫面,盡可能減少工作量。
在 Xcode 中開啟 iOS 專案,並確認 Runner 專案中有 ListTileNativeAdView.xib。
建立 ListTileNativeAdFactory 類別
- 在專案導覽工具的「Runner」群組上按一下滑鼠右鍵,然後選取「New File」,為新類別建立標頭檔案。
- 在範本對話方塊中,選取「Header 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 */
- 從「Runner」群組中選取「New File」,建立 Objective-C 檔案。
- 在下一個對話方塊中,於「File」欄位中輸入
ListTileNativeAdFactory
,然後選取「Empty File」做為檔案類型。
- 點選「下一步」後,系統會請您選取要建立新檔案的資料夾。保持不變,然後點選「建立」。
- 請按照以下方式實作
ListTileNativeFactory
類別。請注意,該類別會在FLTNativeAdFactory
通訊協定中實作createNativeAd()
方法。
工廠類別負責建立用於顯示原生廣告的 View 物件。如程式碼所示,工廠類別會建立 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
檔案,然後呼叫 [FLTGoogleMobileAdsPlugin registerNativeAdFactory]
方法,使用專屬字串 ID (listTile
) 註冊 ListTileNativeAdFactory
。
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 上顯示原生廣告了。
導入 iOS 專用 NativeAdFactory (Swift)
開啟 ios/Podfile
檔案 (或「ios」資料夾下的任何檔案),然後按一下「在 Xcode 中開啟 iOS 模組」,即可開啟 iOS 專案。
準備原生廣告版面配置
您必須有自訂資料檢視 (*.xib
),才能設定原生廣告素材資源。在本程式碼研究室中,系統會使用預先設定的檢視畫面,盡可能減少工作量。
在 Xcode 中開啟 iOS 專案,並確認 Runner 專案中有 ListTileNativeAdView.xib。
建立 ListTileNativeAdFactory 類別
- 在專案導覽工具的「Runner」群組上按一下滑鼠右鍵,然後選取「New File」,為新類別建立標頭檔案。
- 在範本對話方塊中,選取「Swift File」,並將其命名為
ListTileNativeAdFactory
。 - 建立
ListTileNativeAdFactory.swift
檔案後,實作ListNativeAdFactory
類別。
請注意,該類別會在 FLTNativeAdFactory
通訊協定中實作 createNativeAd()
方法。
工廠類別負責建立用於顯示原生廣告的 View 物件。如程式碼所示,工廠類別會建立 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
檔案,然後呼叫 FLTGoogleMobileAdsPlugin.registerNativeAdFactory()
方法,使用專屬字串 ID (listTile
) 註冊 ListTileNativeAdFactory
。
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()
方法中,建立及載入使用ListTileNativeAdFactory
產生原生廣告檢視畫面的NativeAd
。
請注意,系統會使用你為外掛程式註冊工廠時使用的原廠 ID (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(
...
);
}
},
),
);
}
- 在
dispose()
回呼方法中呼叫NativeAd.dispose()
方法,釋出與NativeAd
物件相關聯的資源。
native_inline_page.dart
@override
void dispose() {
// TODO: Dispose a NativeAd object
_ad?.dispose();
super.dispose();
}
大功告成!執行專案,然後按一下首頁的「Native 內嵌廣告」按鈕。廣告載入後,清單中央會顯示原生廣告。
9. 全部完成!
您已完成程式碼研究室。您可以在 「complete」或 「complete_kotlin_swift」資料夾中找到本程式碼研究室的完成程式碼。