1. مقدمة
في هذا الدرس التطبيقي حول الترميز، ستنفّذ إعلان بانر من AdMob وإعلانًا مدمجًا مع المحتوى من AdMob في تطبيق Flutter.
ما ستنشئه
يرشدك هذا الدرس التطبيقي حول الترميز خلال عملية تنفيذ "إعلان بانر مضمّن" و"إعلانات أصلية مضمّنة" من AdMob في تطبيق Flutter باستخدام مكوّن "إعلانات Google على الأجهزة الجوّالة" الإضافي في Flutter.
|
|
إذا واجهت أي مشاكل (مثل أخطاء في الرمز أو أخطاء نحوية أو صياغة غير واضحة وما إلى ذلك) أثناء العمل على هذا الدرس العملي، يُرجى الإبلاغ عن المشكلة باستخدام الرابط الإبلاغ عن خطأ في أسفل يسار الدرس العملي.
ما ستتعلمه
- كيفية ضبط مكوّن Google Mobile Ads الإضافي لـ Flutter
- كيفية عرض إعلانات بانر مضمّنة وإعلانات مقابل مكافأة في تطبيق Flutter
المتطلبات
- الإصدار 4.1 أو إصدار أحدث من "استوديو Android"
- Xcode 12 أو إصدار أحدث (لتطوير تطبيقات iOS)
ما هو تقييمك لمستوى خبرتك في AdMob؟
ما هو تقييمك لمستوى خبرتك في Flutter؟
2. إعداد بيئة تطوير Flutter
تحتاج إلى برنامجَين لإكمال هذا الدرس التطبيقي، وهما حزمة تطوير البرامج (SDK) الخاصة بإطار عمل Flutter ومحرِّر.
يمكنك تشغيل الدرس العملي باستخدام أيّ من الأجهزة التالية:
- جهاز Android أو iOS فعلي متصل بالكمبيوتر وتم ضبطه على "وضع مطور البرامج"
- محاكي iOS (يتطلّب تثبيت أدوات Xcode)
- محاكي Android (يتطلّب الإعداد في "استوديو Android")
- متصفّح (يجب استخدام 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
يحتوي المستودع على ثلاثة مجلدات:
الرمز الأوّلي: الرمز الأوّلي الذي ستنشئه في هذا الدرس التطبيقي حول الترميز.
complete: الرمز البرمجي المكتمل لهذا الدرس التطبيقي حول الترميز. (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/رقم تعريف الوحدة الإعلانية.
إعداد تطبيق "خرائط Google" على أجهزة iOS
لإعداد نظام التشغيل iOS، عليك إضافة تطبيق iOS وإنشاء وحدات إعلانية.
إضافة تطبيق iOS
- في وحدة تحكّم AdMob، انقر على إضافة تطبيق من قائمة التطبيقات.
- عندما يُطلب منك الإجابة عن السؤال هل نشرت تطبيقك على Google Play أو App Store؟، انقر على لا.
- أدخِل
AdMob inline adsفي حقل اسم التطبيق، واختَر iOS كنظام أساسي.

- ليس من الضروري تفعيل مقاييس المستخدم لإكمال هذا الدرس العملي. ومع ذلك، ننصحك بإجراء ذلك لأنّه يتيح لك فهم سلوك المستخدمين بتفصيل أكبر. انقر على إضافة لإكمال العملية.

إنشاء وحدات إعلانية
لإضافة وحدات إعلانية، اتّبِع الخطوات التالية:
- اختَر تطبيق الإعلانات المضمّنة في AdMob من قائمة التطبيقات في وحدة تحكّم AdMob.
- انقر على قائمة الوحدات الإعلانية.
البانر
|
|
الإعلان المدمجة مع المحتوى
|
|
عادةً ما يستغرق بدء عرض الإعلانات في وحدة إعلانية جديدة بضع ساعات.
إذا أردت اختبار سلوك الإعلان على الفور، استخدِم رقم تعريف التطبيق الاختباري وأرقام تعريف الوحدات الإعلانية المُدرَجة في الجدول التالي.
اختياري: استخدام تطبيق يستخدم AdMob ووحدات إعلانية تجريبية
إذا كنت تريد اتّباع الخطوات الواردة في درس تطبيقي حول الترميز بدلاً من إنشاء تطبيق يستخدم AdMob ووحدات إعلانية جديدة بنفسك، يمكنك استخدام معرّف تطبيق يستخدم AdMob الاختباري ومعرّفات الوحدات الإعلانية المُدرَجة في الجداول التالية.
معرّف تطبيق Android/معرّف الوحدة الإعلانية
السلعة | معرّف التطبيق/معرّف الوحدة الإعلانية |
رقم تعريف التطبيق الذي يحقّق الربح عبر AdMob |
|
بانر |
|
مدمج مع المحتوى |
|
معرّف تطبيق iOS أو معرّف الوحدة الإعلانية
السلعة | معرّف التطبيق/معرّف الوحدة الإعلانية |
رقم تعريف التطبيق الذي يحقّق الربح عبر AdMob |
|
بانر |
|
مدمج مع المحتوى |
|
لمزيد من المعلومات عن الإعلانات الاختبارية، يُرجى الاطّلاع على مستندات المطوّرين الخاصة بالإعلانات الاختبارية على Android والإعلانات الاختبارية على iOS.
4. إضافة مكوّن Flutter الإضافي لـ "إعلانات Google على الأجهزة الجوّالة"
يستخدم Flutter المكوّنات الإضافية لتوفير إمكانية الوصول إلى مجموعة كبيرة من الخدمات الخاصة بكل نظام أساسي. تتيح لك المكوّنات الإضافية الوصول إلى الخدمات وواجهات برمجة التطبيقات على كل منصة.
تتيح الإضافة google_mobile_ads تحميل إعلانات البانر والإعلانات البينية والإعلانات مقابل مكافأة والإعلانات المدمَجة مع المحتوى وعرضها باستخدام واجهة برمجة التطبيقات AdMob API.
بما أنّ Flutter هي حزمة تطوير برامج (SDK) متعددة الأنظمة الأساسية، فإنّ المكوّن الإضافي google_mobile_ads ينطبق على كلّ من iOS وAndroid. لذلك، إذا أضفت المكوّن الإضافي إلى تطبيق Flutter، سيتم استخدامه في كلّ من إصدارَي Android وiOS من تطبيق "الإعلانات المضمّنة" على AdMob.
إضافة المكوّن الإضافي "إعلانات Google على الأجهزة الجوّالة" كعنصر تابع
للوصول إلى واجهات برمجة التطبيقات في 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. - أضِف رقم تعريف تطبيقك الذي يستخدم 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. - أضِف مفتاح
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 على الأجهزة الجوّالة"
قبل تحميل الإعلانات، عليك إعداد حزمة "SDK لإعلانات Google على الأجهزة الجوّالة". افتح الملف lib/home_page.dart وعدِّل _initGoogleMobileAds() لبدء إعداد حزمة تطوير البرامج (SDK) قبل تحميل الصفحة الرئيسية.
يُرجى العِلم أنّه عليك تغيير نوع القيمة التي تم إرجاعها لطريقة _initGoogleMobileAds() من Future<dynamic> إلى Future<InitializationStatus> للحصول على نتيجة إعداد حزمة تطوير البرامج (SDK) بعد اكتمالها.
home_page.dart
// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:flutter/material.dart';
...
class HomePage extends StatelessWidget {
...
Future<InitializationStatus> _initGoogleMobileAds() {
// TODO: Initialize Google Mobile Ads SDK
return MobileAds.instance.initialize();
}
}
7. إضافة إعلان بانر
في هذا القسم، يمكنك عرض إعلان بانر في منتصف القائمة، كما هو موضّح في لقطة الشاشة التالية.

- افتح ملف
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وحمِّله لبانر بحجم 320×50 (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" لفتح مشروع Android.

- إذا طُلب منك اختيار نافذة لفتح مشروع جديد، انقر على نافذة جديدة لإبقاء مشروع Flutter مفتوحًا أثناء العمل على مشروع Android.

إنشاء تنسيق إعلان مدمج مع المحتوى
- بعد فتح مشروع Android، انقر بزر الماوس الأيمن على التطبيق من لوحة المشروع في "استوديو Android"، ثم اختَر جديد > ملف موارد 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، ثم اختَر New (جديد) > Java Class (فئة Java).

- أدخِل
ListTileNativeAdFactoryكاسم، ثم اختَر الصف من القائمة.

- بعد ظهور مربّع الحوار صف جديد، اترُك كل الحقول فارغة وانقر على حسنًا.
ستلاحظ أنّه تم إنشاء الفئة 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 في GoogleMobileAdsPlugin قبل أن يمكن استخدامه من جهة Flutter.
- افتح ملف
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" لفتح مشروع Android.

- إذا طُلب منك اختيار نافذة لفتح مشروع جديد، انقر على نافذة جديدة لإبقاء مشروع Flutter مفتوحًا أثناء العمل على مشروع Android.

إنشاء تنسيق إعلان مدمج مع المحتوى
- بعد فتح مشروع Android، انقر بزر الماوس الأيمن على التطبيق من لوحة المشروع في "استوديو Android"، ثم اختَر جديد > ملف موارد 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كاسم، ثم اختَر الصف من القائمة.

- ستلاحظ أنّه تم إنشاء الفئة
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 في 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)، وانقر على فتح وحدة iOS في Xcode لفتح مشروع iOS.

إعداد تخطيط إعلان مدمج مع المحتوى
يجب أن يكون لديك عرض مخصّص (*.xib) لتصميم مواد عرض الإعلانات المدمجة مع المحتوى. في هذا الدرس التطبيقي حول الترميز، يتم استخدام طريقة العرض المُعدّة مسبقًا لتقليل جهودك.
بعد فتح مشروع iOS في Xcode، تأكَّد من أنّ الملف ListTileNativeAdView.xib متوفّر في مشروع Runner.

إنشاء فئة ListTileNativeAdFactory
- من "مستكشف المشروع" (Project navigator)، انقر بزر الماوس الأيمن على مجموعة 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
تسجيل فئة ListTileNativeAdFacotry
يجب تسجيل تنفيذ FLTNativeAdFactory في FLTGoogleMobileAdsPlugin قبل أن تتمكّن من استخدامه من جهة Flutter.
افتح ملف AppDelegate.m، وسجِّل ListTileNativeAdFactory باستخدام معرّف سلسلة فريد (listTile) عن طريق استدعاء طريقة [FLTGoogleMobileAdsPlugin registerNativeAdFactory].
AppDelegate.m
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
// TODO: Import ListTileNativeAdFactory.h
#import "ListTileNativeAdFactory.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// TODO: Register ListTileNativeAdFactory
ListTileNativeAdFactory *listTileFactory = [[ListTileNativeAdFactory alloc] init];
[FLTGoogleMobileAdsPlugin registerNativeAdFactory:self
factoryId:@"listTile"
nativeAdFactory:listTileFactory];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
أنت الآن مستعد لاستخدام ListTileNativeAdFactory لعرض "الإعلانات المدمجة مع المحتوى" على iOS.
تنفيذ NativeAdFactory لنظام التشغيل iOS (Swift)
افتح ملف ios/Podfile (أو أي ملف ضمن مجلد ios)، وانقر على فتح وحدة iOS في Xcode لفتح مشروع iOS.

إعداد تخطيط إعلان مدمج مع المحتوى
يجب أن يكون لديك عرض مخصّص (*.xib) لتصميم مواد عرض الإعلانات المدمجة مع المحتوى. في هذا الدرس التطبيقي حول الترميز، يتم استخدام طريقة العرض المُعدّة مسبقًا لتقليل جهودك.
بعد فتح مشروع iOS في Xcode، تأكَّد من أنّ الملف ListTileNativeAdView.xib متوفّر في مشروع Runner.

إنشاء فئة ListTileNativeAdFactory
- من "مستكشف المشروع" (Project navigator)، انقر بزر الماوس الأيمن على مجموعة 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
}
}
تسجيل فئة ListTileNativeAdFacotry
يجب تسجيل تنفيذ FLTNativeAdFactory في FLTGoogleMobileAdsPlugin قبل أن تتمكّن من استخدامه من جهة Flutter.
افتح ملف AppDelegate.m، وسجِّل ListTileNativeAdFactory باستخدام معرّف سلسلة فريد (listTile) عن طريق استدعاء طريقة FLTGoogleMobileAdsPlugin.registerNativeAdFactory().
AppDelegate.swift
import UIKit
import Flutter
// TODO: Import google_mobile_ads
import google_mobile_ads
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
// TODO: Register ListTileNativeAdFactory
let listTileFactory = ListTileNativeAdFactory()
FLTGoogleMobileAdsPlugin.registerNativeAdFactory(
self, factoryId: "listTile", nativeAdFactory: listTileFactory)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
أنت الآن مستعد لاستخدام ListTileNativeAdFactory لعرض "الإعلانات المدمجة مع المحتوى" على iOS.
دمج الإعلان المدمج مع المحتوى مع أدوات Flutter
- افتح ملف
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- أكملت الخطوات بنجاح
لقد أكملت تجربة البرمجة. يمكنك العثور على الرمز البرمجي المكتمل لهذا الدرس التطبيقي حول الترميز في المجلد
complete أو المجلد
complete_kotlin_swift.

