1. מבוא
ב-Codelab הזה, תטמיעו מודעת באנר של AdMob ומודעה משולבת בתוכן הדף של AdMob בתוך אפליקציית Flutter.
מה תפַתחו
ב-codelab הזה מוסבר איך מטמיעים מודעת באנר מוטמעת של AdMob ומודעות מותאמות מוטמעות של AdMob באפליקציית Flutter באמצעות הפלאגין Google Mobile Ads ל-Flutter.
|
|
אם נתקלתם בבעיות (באגים בקוד, שגיאות דקדוק, ניסוח לא ברור וכו') במהלך העבודה ב-codelab הזה, אתם יכולים לדווח על הבעיה באמצעות הקישור דיווח על טעות בפינה הימנית התחתונה של ה-codelab.
מה תלמדו
- איך מגדירים את Google Mobile Ads Flutter plugin
- איך מטמיעים מודעת באנר מוטמעת ומודעות מתגמלות באפליקציית Flutter
מה תצטרכו
- Android Studio 4.1 ואילך
- Xcode 12 ואילך (לפיתוח ל-iOS)
מה רמת הניסיון שלך ב-AdMob?
מה רמת הניסיון שלך עם Flutter?
2. הגדרת סביבת הפיתוח של Flutter
כדי להשלים את שיעור ה-Lab הזה, תצטרכו שני סוגי תוכנה: Flutter SDK ועורך.
אפשר להריץ את ה-codelab באמצעות כל אחד מהמכשירים הבאים:
- מכשיר פיזי עם 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
המאגר מכיל שלוש תיקיות:
-
starter: קוד התחלתי שתיצרו ב-Codelab הזה. -
complete: קוד מלא ל-Codelab הזה. (Java ו-Objective-C לקוד Native) -
complete_kotlin_swift: קוד מלא ל-Codelab הזה. (Kotlin ו-Swift לקוד Native)
3. הגדרת אפליקציה שמקושרת ל-AdMob ויחידות מודעות
מכיוון ש-Flutter הוא SDK חוצה פלטפורמות, צריך להוסיף אפליקציה ויחידות מודעות גם ל-Android וגם ל-iOS ב-AdMob.
הגדרה ב-Android
כדי להגדיר את האפליקציה ל-Android, צריך להוסיף אפליקציית Android וליצור יחידות של מודעות.
הוספת אפליקציה ל-Android
- ב-AdMob console, בתפריט Apps, לוחצים על ADD APP.
- כשמוצגת השאלה האם פרסמת את האפליקציה שלך ב-Google Play או ב-App Store?, לוחצים על לא.
- מזינים
AdMob inline adsבשדה של שם האפליקציה ובוחרים באפשרות Android בתור הפלטפורמה.

- אין צורך להפעיל את מדדי המשתמשים כדי להשלים את ה-codelab הזה. עם זאת, מומלץ לעשות זאת כדי להבין את התנהגות המשתמשים בצורה מפורטת יותר. לוחצים על הוספה כדי להשלים את התהליך.

יצירת יחידות של מודעות
כדי להוסיף יחידות של מודעות:
- בתפריט Apps במסוף AdMob, בוחרים באפליקציה AdMob inline ads.
- לוחצים על התפריט יחידות של מודעות.
באנר
|
|
Native
|
|
בדרך כלל חולפות כמה שעות עד שיחידת מודעות חדשה יכולה להציג מודעות.
אם רוצים לבדוק את התנהגות המודעה באופן מיידי, צריך להשתמש במזהה אפליקציית הבדיקה ובמזהים של יחידות המודעות שמפורטים בטבלאות של מזהה אפליקציית Android ומזהה יחידת המודעות, ושל מזהה אפליקציית iOS ומזהה יחידת המודעות.
הגדרה ל-iOS
כדי להגדיר את האפשרות הזו ב-iOS, צריך להוסיף אפליקציית iOS וליצור יחידות של מודעות.
הוספת אפליקציה ל-iOS
- ב-AdMob console, בתפריט Apps, לוחצים על ADD APP.
- כשמוצגת השאלה האם פרסמת את האפליקציה שלך ב-Google Play או ב-App Store?, לוחצים על לא.
- מזינים
AdMob inline adsבשדה של שם האפליקציה ובוחרים באפשרות iOS בתור הפלטפורמה.

- אין צורך להפעיל את מדדי המשתמשים כדי להשלים את ה-codelab הזה. עם זאת, מומלץ לעשות זאת כדי להבין את התנהגות המשתמשים בצורה מפורטת יותר. לוחצים על הוספה כדי להשלים את התהליך.

יצירת יחידות של מודעות
כדי להוסיף יחידות של מודעות:
- בתפריט Apps במסוף AdMob, בוחרים באפליקציה AdMob inline ads.
- לוחצים על התפריט יחידות של מודעות.
באנר
|
|
Native
|
|
בדרך כלל חולפות כמה שעות עד שיחידת מודעות חדשה יכולה להציג מודעות.
אם רוצים לבדוק את התנהגות המודעה באופן מיידי, אפשר להשתמש במזהה אפליקציית הבדיקה ובמזהים של יחידות המודעות שמפורטים בטבלה הבאה.
אופציונלי: שימוש באפליקציית בדיקה וביחידות מודעות של AdMob
אם אתם רוצים לעקוב אחרי ה-codelab במקום ליצור אפליקציה חדשה ויחידות מודעות בעצמכם, אתם יכולים להשתמש במזהה האפליקציה שמקושרת ל-AdMob ובמזהים של יחידות המודעות לבדיקה שמפורטים בטבלאות הבאות.
מזהה אפליקציה ל-Android או מזהה יחידת מודעות
פריט | מזהה אפליקציה/מזהה יחידת מודעות |
מזהה האפליקציה שמקושרת ל-AdMob |
|
מודעת באנר |
|
מותאם |
|
מזהה אפליקציה ל-iOS או מזהה יחידת מודעות
פריט | מזהה אפליקציה/מזהה יחידת מודעות |
מזהה האפליקציה שמקושרת ל-AdMob |
|
מודעת באנר |
|
מותאם |
|
מידע נוסף על מודעות בדיקה זמין בתיעוד למפתחים בנושא מודעות בדיקה ל-Android ומודעות בדיקה ל-iOS.
4. הוספת Google Mobile Ads Flutter plugin
Flutter משתמשת בפלאגינים כדי לספק גישה למגוון רחב של שירותים ספציפיים לפלטפורמה. תוספים מאפשרים לכם לגשת לשירותים ולממשקי API בכל פלטפורמה.
התוסף google_mobile_ads תומך בטעינה ובהצגה של מודעות באנר, מודעות מעברון, מודעות מתגמלות ומודעות מותאמות באמצעות AdMob API.
Flutter הוא SDK חוצה פלטפורמות, ולכן הפלאגין google_mobile_ads רלוונטי גם ל-iOS וגם ל-Android. לכן, אם מוסיפים את הפלאגין לאפליקציית Flutter, הוא ישמש גם את גרסת Android וגם את גרסת iOS של אפליקציית המודעות המוטמעות של AdMob.
הוספה של הפלאגין Google Mobile Ads כתלות
כדי לגשת לממשקי ה-API של AdMob מהפרויקט מודעות משולבות בתוכן הדף של AdMob, מוסיפים את google_mobile_ads כתלות לקובץ pubspec.yaml שנמצא בהרמה הבסיסית (root) של הפרויקט.
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 inline ads.

עדכון הקובץ 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. אתחול Google Mobile Ads SDK
לפני טעינת המודעות, צריך להפעיל את Google Mobile Ads SDK. פותחים את הקובץ 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, מוסיפים את החברים וה-methods הבאים למודעת באנר.
הערה: הסמל _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). שימו לב: event listener לאירועי מודעות מוגדר לעדכן את ממשק המשתמש (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, צריך להפעיל את methodBannerAd.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 לכל פלטפורמה. ה-NativeAdFactory משמש ליצירת תצוגת מודעה מותאמת שספציפית לפלטפורמה (NativeAdView ב-Android ו-GADNativeAdView ב-iOS) מאובייקט של מודעה מותאמת (NativeAd ב-Android ו-GADNativeAd ב-iOS).
הטמעה של NativeAdFactory ל-Android (Java)
- פותחים את הקובץ
android/build.gradle(או כל קובץ אחר בתיקייה android) ולוחצים על Open for Editing in Android Studio (פתיחה לעריכה ב-Android Studio) כדי לפתוח פרויקט Android.

- אם מתבקשים לבחור חלון כדי לפתוח פרויקט חדש, לוחצים על New Window כדי שפרויקט Flutter יישאר פתוח בזמן שאתם עובדים על פרויקט Android.

יצירה של פריסת מודעות מותאמות
- פותחים את פרויקט Android, לוחצים לחיצה ימנית על app בחלונית הפרויקט ב-Android Studio ובוחרים באפשרות New > Android Resource File (חדש > קובץ משאבים של Android) בתפריט ההקשר.

- בתיבת הדו-שיח New Resource File (קובץ משאבים חדש), מזינים
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
- בחלונית Project (פרויקט), לוחצים לחיצה ימנית על החבילה com.codelab.flutter.admobinlineads ובוחרים באפשרות New > Java Class (חדש > מחלקה של Java).

- מזינים
ListTileNativeAdFactoryבתור השם ובוחרים באפשרות Class (כיתה) מהרשימה.

- אחרי שמופיעה תיבת הדו-שיח כיתה חדשה, משאירים את כל השדות ריקים ולוחצים על אישור.
תוכלו לראות שהכיתה ListTileNativeAdFactory נוצרה בחבילה com.codelab.flutter.admobinlineads.

- מטמיעים את המחלקה
ListTileNativeAdFactoryבאופן הבא. שימו לב שהמחלקה מטמיעה את השיטהcreateNativeAd()בממשקGoogleMobileAdsPlugin.NativeAdFactory.
מחלקת ה-factory אחראית ליצירת אובייקט view לעיבוד מודעה מותאמת. כפי שאפשר לראות מהקוד, מחלקת הפקטורי (factory) יוצרת 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) ולוחצים על Open for Editing in Android Studio (פתיחה לעריכה ב-Android Studio) כדי לפתוח פרויקט Android.

- אם מתבקשים לבחור חלון כדי לפתוח פרויקט חדש, לוחצים על New Window כדי שפרויקט Flutter יישאר פתוח בזמן שאתם עובדים על פרויקט Android.

יצירה של פריסת מודעות מותאמות
- פותחים את פרויקט Android, לוחצים לחיצה ימנית על app בחלונית הפרויקט ב-Android Studio ובוחרים באפשרות New > Android Resource File (חדש > קובץ משאבים של Android) בתפריט ההקשר.

- בתיבת הדו-שיח New Resource File (קובץ משאבים חדש), מזינים
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
- בחלונית Project (פרויקט), לוחצים לחיצה ימנית על החבילה com.codelab.flutter.admobinlineads ובוחרים באפשרות New > Kotlin File/Class (חדש > קובץ או סיווג של Kotlin).

- מזינים
ListTileNativeAdFactoryבתור השם ובוחרים באפשרות Class (כיתה) מהרשימה.

- תוכלו לראות שהכיתה
ListTileNativeAdFactoryנוצרה בחבילהcom.codelab.flutter.admobinlineads. - מטמיעים את המחלקה
ListTileNativeAdFactoryבאופן הבא. שימו לב שהמחלקה מטמיעה את השיטהcreateNativeAd()בממשקGoogleMobileAdsPlugin.NativeAdFactory.
מחלקת ה-factory אחראית ליצירת אובייקט view לעיבוד מודעה מותאמת. כפי שאפשר לראות מהקוד, מחלקת הפקטורי (factory) יוצרת 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(). - רושמים את המחלקה
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) ולוחצים על Open iOS module in Xcode (פתיחת מודול iOS ב-Xcode) כדי לפתוח פרויקט iOS.

הכנת פריסת מודעות מותאמות
צריך להגדיר תצוגה בהתאמה אישית (*.xib) כדי להציג את נכסי המודעות המותאמות. ב-codelab הזה, נעשה שימוש בתצוגה שהוגדרה מראש כדי לצמצם את המאמצים שלכם.
אחרי שפותחים את פרויקט 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 על ידי בחירה באפשרות New File (קובץ חדש) בקבוצה Runner (מפעיל).
- בתיבת הדו-שיח הבאה, מזינים
ListTileNativeAdFactoryבשדה File (קובץ) ובוחרים באפשרות Empty File (קובץ ריק) כסוג הקובץ.

- אחרי שלוחצים על הבא, מתבקשים לבחור תיקייה שבה ייצור הקובץ החדש. משאירים את כל ההגדרות ללא שינוי ולוחצים על יצירה.

- מטמיעים את המחלקה
ListTileNativeFactoryבאופן הבא. שימו לב שהמחלקה מטמיעה את השיטהcreateNativeAd()בפרוטוקולFLTNativeAdFactory.
מחלקת ה-factory אחראית ליצירת אובייקט view לעיבוד מודעה מותאמת. כפי שאפשר לראות מהקוד, מחלקת הפקטורי (factory) יוצרת 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) באמצעות קריאה ל-method [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) ולוחצים על Open iOS module in Xcode (פתיחת מודול iOS ב-Xcode) כדי לפתוח פרויקט iOS.

הכנת פריסת מודעות מותאמות
צריך להגדיר תצוגה בהתאמה אישית (*.xib) כדי להציג את נכסי המודעות המותאמות. ב-codelab הזה, נעשה שימוש בתצוגה שהוגדרה מראש כדי לצמצם את המאמצים שלכם.
אחרי שפותחים את פרויקט iOS ב-Xcode, מוודאים שהקובץ ListTileNativeAdView.xib קיים בפרויקט Runner.

יצירת המחלקה ListTileNativeAdFactory
- בסרגל הניווט של הפרויקט, לוחצים לחיצה ימנית על הקבוצה Runner ובוחרים באפשרות New File (קובץ חדש) כדי ליצור קובץ כותרת בשביל המחלקה החדשה.

- בתיבת הדו-שיח של התבנית, בוחרים באפשרות קובץ Swift ונותנים לו את השם
ListTileNativeAdFactory. - אחרי שיוצרים את הקובץ
ListTileNativeAdFactory.swift, מטמיעים את המחלקהListNativeAdFactory.
שימו לב שהמחלקה מטמיעה את השיטה createNativeAd() בפרוטוקול FLTNativeAdFactory.
מחלקת ה-factory אחראית ליצירת אובייקט תצוגה לעיבוד מודעה מותאמת. כפי שאפשר לראות מהקוד, מחלקת הפקטורי (factory) יוצרת 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) באמצעות קריאה ל-method 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, מוסיפים את החברים וה-methods הבאים למודעה מותאמת.
הערה: הסמל _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;
}
...
}
- ב-method
initState(), יוצרים וטועניםNativeAdשמשתמש ב-ListTileNativeAdFactoryכדי ליצור תצוגה של מודעה מותאמת.
שימו לב: נעשה שימוש באותו מזהה פקטורי (factory) (listTile) ששימש לרישום הפקטורי (factory) בתוסף.
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, צריך להפעיל את methodNativeAd.dispose()בשיטת קריאה חוזרתdispose().
native_inline_page.dart
@override
void dispose() {
// TODO: Dispose a NativeAd object
_ad?.dispose();
super.dispose();
}
זהו! מריצים את הפרויקט ולוחצים על הלחצן Native inline ad (מודעה משולבת בתוכן הדף) בדף הבית. אחרי שמודעה נטענת, מודעה מותאמת מופיעה באמצע הרשימה.

9. הכול מוכן!
סיימתם את ה-Codelab. הקוד המלא של ה-Codelab הזה נמצא בתיקייה
complete או בתיקייה
complete_kotlin_swift.

