1. Giới thiệu
Sản phẩm bạn sẽ tạo ra
Lớp học lập trình này hướng dẫn bạn cách thêm một biểu ngữ, quảng cáo xen kẽ và quảng cáo có tặng thưởng vào một ứng dụng có tên là Awesome Drawing Quiz (Đố vui vẽ tranh siêu đỉnh), một trò chơi cho phép người chơi đoán tên của bức vẽ.
|
|
Nếu bạn gặp vấn đề (lỗi trong đoạn mã, lỗi ngữ pháp, từ ngữ không rõ ràng) khi thực hành theo lớp học lập trình này, vui lòng báo cáo vấn đề bằng cách nhấp vào đường liên kết Báo cáo lỗi ở góc dưới bên trái của lớp học lập trình.
Kiến thức bạn sẽ học được
- Cách thiết lập trình bổ trợ Google Mobile Ads AdMob
- Cách triển khai quảng cáo biểu ngữ, quảng cáo xen kẽ và quảng cáo có tặng thưởng trong ứng dụng Flutter
Bạn cần có
- Android Studio 4.1 trở lên
- Xcode 12 trở lên (để phát triển iOS)
Bạn đánh giá thế nào về mức độ kinh nghiệm của mình với AdMob?
Bạn đánh giá thế nào về trình độ kinh nghiệm của mình với Flutter?
2. Thiết lập môi trường phát triển Flutter
Bạn cần có 2 phần mềm để hoàn thành bài thực hành này: Flutter SDK và một trình chỉnh sửa.
Bạn có thể chạy lớp học lập trình này bằng bất kỳ thiết bị nào sau đây:
- Một thiết bị Android hoặc iOS thực được kết nối với máy tính và được đặt ở Chế độ nhà phát triển.
- Trình mô phỏng iOS (bạn cần cài đặt các công cụ Xcode).
- Trình mô phỏng Android (cần thiết lập trong Android Studio).
- Một trình duyệt (bạn cần có Chrome để gỡ lỗi).
- Dưới dạng ứng dụng máy tính cho Windows, Linux hoặc macOS. Bạn phải phát triển trên nền tảng mà bạn dự định triển khai. Vì vậy, nếu muốn phát triển một ứng dụng máy tính cho Windows, bạn phải phát triển trên Windows để truy cập vào chuỗi bản dựng thích hợp. Có những yêu cầu cụ thể theo hệ điều hành được đề cập chi tiết trên docs.flutter.dev/desktop.
Tải mã xuống
Sau khi tải tệp zip xuống, hãy giải nén nội dung của tệp đó. Bạn sẽ có một thư mục có tên admob-ads-in-flutter-master.
Ngoài ra, bạn có thể sao chép kho lưu trữ GitHub từ dòng lệnh:
$ git clone https://github.com/googlecodelabs/admob-ads-in-flutter
Kho lưu trữ này chứa hai thư mục:
starter – Mã khởi đầu mà bạn sẽ tạo trong lớp học lập trình này.
complete – Mã hoàn chỉnh cho lớp học lập trình này.
3. Thiết lập ứng dụng và đơn vị quảng cáo AdMob
Vì Flutter là một SDK đa nền tảng, nên bạn cần thêm một ứng dụng và đơn vị quảng cáo cho cả Android và iOS trong AdMob.
Thiết lập cho Android
Để thiết lập cho Android, bạn cần thêm một ứng dụng Android và tạo đơn vị quảng cáo.
Thêm ứng dụng Android
- Trong bảng điều khiển AdMob, hãy nhấp vào THÊM ỨNG DỤNG trong trình đơn Ứng dụng.
- Khi được hỏi Bạn đã xuất bản ứng dụng của mình trên Google Play hoặc App Store chưa?, hãy nhấp vào KHÔNG.
- Nhập
Awesome Drawing Quizvào trường tên ứng dụng rồi chọn Android làm nền tảng.

- Bạn không cần bật chỉ số người dùng để hoàn tất lớp học lập trình này. Tuy nhiên, bạn nên làm việc này vì nó giúp bạn hiểu rõ hơn về hành vi của người dùng. Nhấp vào THÊM để hoàn tất quy trình.

Tạo đơn vị quảng cáo
Cách bắt đầu thêm đơn vị quảng cáo vào AdMob:
- Chọn Awesome Drawing Quiz trong trình đơn Ứng dụng trên bảng điều khiển AdMob.
- Nhấp vào trình đơn Đơn vị quảng cáo.
Biểu ngữ
|
|
Quảng cáo xen kẽ
|
|
Quảng cáo có tặng thưởng
|
|
Thường mất vài giờ để một đơn vị quảng cáo mới có thể phân phát quảng cáo.
Nếu bạn muốn kiểm thử ngay hành vi của quảng cáo, hãy sử dụng mã ứng dụng và mã đơn vị quảng cáo thử nghiệm có trong bảng mã ứng dụng/mã đơn vị quảng cáo Android và mã ứng dụng/mã đơn vị quảng cáo iOS.
Thiết lập cho iOS
Để thiết lập cho iOS, bạn cần thêm một ứng dụng iOS và tạo đơn vị quảng cáo.
Thêm ứng dụng iOS
- Trong bảng điều khiển AdMob, hãy nhấp vào THÊM ỨNG DỤNG trong trình đơn Ứng dụng.
- Khi được hỏi Bạn đã xuất bản ứng dụng của mình trên Google Play hoặc App Store chưa?, hãy nhấp vào KHÔNG.
- Nhập
Awesome Drawing Quizvào trường tên ứng dụng rồi chọn iOS làm nền tảng.

- Bạn không cần bật chỉ số người dùng để hoàn tất lớp học lập trình này. Tuy nhiên, bạn nên làm việc này vì nó giúp bạn hiểu rõ hơn về hành vi của người dùng. Nhấp vào THÊM để hoàn tất quy trình.

Tạo đơn vị quảng cáo
Cách thêm đơn vị quảng cáo:
- Chọn ứng dụng Awesome Drawing Quiz trong trình đơn Ứng dụng trong bảng điều khiển AdMob.
- Nhấp vào trình đơn Đơn vị quảng cáo.
Biểu ngữ
|
|
Quảng cáo xen kẽ
|
|
Quảng cáo có tặng thưởng
|
|
Thường mất vài giờ để một đơn vị quảng cáo mới có thể phân phát quảng cáo.
Nếu bạn muốn kiểm tra ngay hành vi của quảng cáo, hãy sử dụng mã ứng dụng thử nghiệm và mã đơn vị quảng cáo được liệt kê trong bảng sau.
Không bắt buộc: Sử dụng ứng dụng và đơn vị quảng cáo thử nghiệm của AdMob
Nếu muốn làm theo lớp học lập trình thay vì tự tạo ứng dụng và đơn vị quảng cáo mới, bạn có thể sử dụng mã ứng dụng AdMob và mã đơn vị quảng cáo thử nghiệm được liệt kê trong các bảng sau.
Mã ứng dụng Android/mã đơn vị quảng cáo
Item | mã ứng dụng/mã đơn vị quảng cáo |
Mã ứng dụng AdMob |
|
Biểu ngữ |
|
Quảng cáo xen kẽ |
|
Được thưởng |
|
Mã ứng dụng/mã đơn vị quảng cáo iOS
Item | mã ứng dụng/mã đơn vị quảng cáo |
Mã ứng dụng AdMob |
|
Biểu ngữ |
|
Quảng cáo xen kẽ |
|
Được thưởng |
|
Để biết thêm thông tin về quảng cáo thử nghiệm, hãy xem tài liệu dành cho nhà phát triển về quảng cáo thử nghiệm trên Android và quảng cáo thử nghiệm trên iOS.
4. Thêm trình bổ trợ Google Mobile Ads cho Flutter
Flutter sử dụng các trình bổ trợ để cung cấp quyền truy cập vào nhiều dịch vụ dành riêng cho nền tảng. Các trình bổ trợ cho phép bạn truy cập vào các dịch vụ và API trên mỗi nền tảng.
Trình bổ trợ google_mobile_ads hỗ trợ tải và hiển thị quảng cáo biểu ngữ, quảng cáo xen kẽ, quảng cáo có tặng thưởng và quảng cáo gốc bằng API AdMob.
Vì Flutter là một SDK đa nền tảng, nên trình bổ trợ google_mobile_ads có thể áp dụng cho cả iOS và Android. Vì vậy, nếu bạn thêm trình bổ trợ này vào ứng dụng Flutter, thì cả phiên bản Android và iOS của ứng dụng quảng cáo trong dòng AdMob đều sẽ sử dụng trình bổ trợ này.
Thêm trình bổ trợ Google Mobile Ads làm phần phụ thuộc
Để truy cập vào các API AdMob từ dự án quảng cáo AdMob trong dòng, hãy thêm google_mobile_ads làm phần phụ thuộc vào tệp pubspec.yaml nằm ở thư mục gốc của dự án.
pubspec.yaml
...
environment:
# TODO: Update the minimum sdk version to 2.12.0 to support null safety.
sdk: ">=2.17.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
google_fonts: ^3.0.1
# TODO: Add google_mobile_ads as a dependency
google_mobile_ads: ^1.2.0
...
Nhấp vào Pub get để cài đặt trình bổ trợ trong dự án Awesome Drawing Quiz.

Cập nhật tệp AndroidManifest.xml (Android)
- Mở tệp
android/app/src/main/AndroidManifest.xmltrong Android Studio. - Thêm mã ứng dụng AdMob bằng cách thêm thẻ
<meta-data>có tên làcom.google.android.gms.ads.APPLICATION_ID. Ví dụ: nếu mã ứng dụng AdMob của bạn làca-app-pub-3940256099942544~3347511713, thì bạn cần thêm các dòng sau vào tệpAndroidManifest.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>
Cập nhật Info.plist (iOS)
- Mở tệp
ios/Runner/Info.plisttrong Android Studio. - Thêm khoá
GADApplicationIdentifiercó giá trị chuỗi là mã ứng dụng AdMob của bạn. Ví dụ: nếu mã ứng dụng AdMob của bạn làca-app-pub-3940256099942544~1458002511, thì bạn cần thêm các dòng sau vào tệpInfo.plist.
ios/Runner/Info.plist
...
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-3940256099942544~1458002511</string>
...
5. Thêm một lớp trợ giúp cho quảng cáo
Tạo một tệp mới có tên ad_helper.dart trong thư mục lib. Sau đó, hãy triển khai lớp AdHelper. Lớp này cung cấp mã ứng dụng AdMob và mã đơn vị quảng cáo cho Android và iOS.
Đảm bảo rằng bạn thay thế mã ứng dụng AdMob (ca-app-pub-xxxxxx~yyyyy) và mã đơn vị quảng cáo (ca-app-pub-xxxxxxx/yyyyyyyy) bằng các mã nhận dạng mà bạn đã tạo trong bước trước.
lib/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 interstitialAdUnitId {
if (Platform.isAndroid) {
return '<YOUR_ANDROID_INTERSTITIAL_AD_UNIT_ID>';
} else if (Platform.isIOS) {
return '<YOUR_IOS_INTERSTITIAL_AD_UNIT_ID>';
} else {
throw UnsupportedError('Unsupported platform');
}
}
static String get rewardedAdUnitId {
if (Platform.isAndroid) {
return '<YOUR_ANDROID_REWARDED_AD_UNIT_ID>';
} else if (Platform.isIOS) {
return '<YOUR_IOS_REWARDED_AD_UNIT_ID>';
} else {
throw UnsupportedError('Unsupported platform');
}
}
}
Hãy sử dụng đoạn mã sau nếu bạn muốn sử dụng mã ứng dụng AdMob thử nghiệm và mã đơn vị quảng cáo thử nghiệm.
lib/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';
} else {
throw new UnsupportedError('Unsupported platform');
}
}
static String get interstitialAdUnitId {
if (Platform.isAndroid) {
return "ca-app-pub-3940256099942544/1033173712";
} else if (Platform.isIOS) {
return "ca-app-pub-3940256099942544/4411468910";
} else {
throw new UnsupportedError("Unsupported platform");
}
}
static String get rewardedAdUnitId {
if (Platform.isAndroid) {
return "ca-app-pub-3940256099942544/5224354917";
} else if (Platform.isIOS) {
return "ca-app-pub-3940256099942544/1712485313";
} else {
throw new UnsupportedError("Unsupported platform");
}
}
}
6. Khởi chạy SDK Quảng cáo của Google trên thiết bị di động
Trước khi tải quảng cáo, bạn cần khởi chạy SDK Quảng cáo của Google trên thiết bị di động. Mở tệp lib/home_route.dart rồi sửa đổi _initGoogleMobileAds() để khởi chạy SDK trước khi trang chủ được tải.
Xin lưu ý rằng bạn cần thay đổi kiểu dữ liệu trả về của phương thức _initGoogleMobileAds() từ Future<dynamic> thành Future<InitializationStatus> để nhận được kết quả khởi chạy SDK sau khi hoàn tất.
home_route.dart
// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:flutter/material.dart';
...
class HomeRoute extends StatelessWidget {
...
Future<InitializationStatus> _initGoogleMobileAds() {
// TODO: Initialize Google Mobile Ads SDK
return MobileAds.instance.initialize();
}
}
7. Thêm quảng cáo biểu ngữ
Trong phần này, bạn sẽ hiển thị một quảng cáo biểu ngữ ở đầu màn hình trò chơi, như trong ảnh chụp màn hình sau.

- Mở tệp
lib/game_route.dartrồi nhậpad_manager.dart - Nhập
ad_helper.dartvàgoogle_mobile_ads.dartbằng cách thêm các dòng sau:
lib/game_route.dart
...
// TODO: Import ad_helper.dart
import 'package:awesome_drawing_quiz/ad_helper.dart';
// TODO: Import google_mobile_ads.dart
import 'package:google_mobile_ads/google_mobile_ads.dart';
class GameRoute extends StatefulWidget {
...
}
- Trong lớp
_GameRouteState, hãy thêm các thành phần sau cho quảng cáo biểu ngữ.
lib/game_route.dart
class _GameRouteState extends State<GameRoute> implements QuizEventListener {
...
// TODO: Add _bannerAd
BannerAd? _bannerAd;
...
}
- Trong phương thức
initState(), hãy tạo và tải mộtBannerAdcho biểu ngữ 320x50 (AdSize.banner). Xin lưu ý rằng bạn phải định cấu hình một trình nghe sự kiện quảng cáo để cập nhật giao diện người dùng (setState()) khi một quảng cáo được tải .
lib/game_route.dart
@override
void initState() {
...
// TODO: Load a banner ad
BannerAd(
adUnitId: AdHelper.bannerAdUnitId,
request: AdRequest(),
size: AdSize.banner,
listener: BannerAdListener(
onAdLoaded: (ad) {
setState(() {
_bannerAd = ad as BannerAd;
});
},
onAdFailedToLoad: (ad, err) {
print('Failed to load a banner ad: ${err.message}');
ad.dispose();
},
),
).load();
}
- Sửa đổi phương thức
build()để hiển thị quảng cáo biểu ngữ khi có.
lib/game_route.dart
@override
Widget build(BuildContext context) {
return Scaffold(
...
body: SafeArea(
child: Stack(
children: [
Center(
...
),
// TODO: Display a banner when ready
if (_bannerAd != null)
Align(
alignment: Alignment.topCenter,
child: Container(
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
),
),
],
),
),
...
);
}
- Giải phóng tài nguyên được liên kết với đối tượng
BannerAdbằng cách gọi phương thứcBannerAd.dispose()trong phương thức gọi lạidispose().
lib/game_route.dart
@override
void dispose() {
// TODO: Dispose a BannerAd object
_bannerAd?.dispose();
...
super.dispose();
}
Vậy là xong! Chạy dự án và bắt đầu một trò chơi mới. Sau khi quảng cáo được tải, bạn sẽ thấy một quảng cáo biểu ngữ ở đầu màn hình.

8. Thêm quảng cáo xen kẽ
Trong phần này, bạn sẽ hiển thị một quảng cáo xen kẽ sau khi trò chơi kết thúc (tổng cộng 5 cấp độ).
- Mở tệp
lib/game_route.dart - Trong lớp
_GameRouteState, hãy thêm các thành phần và phương thức sau cho quảng cáo xen kẽ.
Xin lưu ý rằng trình nghe sự kiện quảng cáo được định cấu hình để kiểm tra xem quảng cáo đã sẵn sàng hay chưa (onAdLoaded() và onAdFailedToLoad()) và hiển thị màn hình chính của ứng dụng khi quảng cáo bị đóng (onAdDismissedFullScreenContent())
lib/game_route.dart
class _GameRouteState extends State<GameRoute> implements QuizEventListener {
...
// TODO: Add _interstitialAd
InterstitialAd? _interstitialAd;
// TODO: Implement _loadInterstitialAd()
void _loadInterstitialAd() {
InterstitialAd.load(
adUnitId: AdHelper.interstitialAdUnitId,
request: AdRequest(),
adLoadCallback: InterstitialAdLoadCallback(
onAdLoaded: (ad) {
ad.fullScreenContentCallback = FullScreenContentCallback(
onAdDismissedFullScreenContent: (ad) {
_moveToHome();
},
);
setState(() {
_interstitialAd = ad;
});
},
onAdFailedToLoad: (err) {
print('Failed to load an interstitial ad: ${err.message}');
},
),
);
}
...
}
- Trong lớp học lập trình này, quảng cáo xen kẽ sẽ xuất hiện sau khi người dùng hoàn thành 5 cấp độ. Để giảm thiểu các yêu cầu quảng cáo không cần thiết, hãy yêu cầu quảng cáo khi người dùng đạt đến cấp độ 3.
Trong phương thức onNewLevel(), hãy thêm các dòng sau.
lib/game_route.dart
@override
void onNewLevel(int level, Drawing drawing, String clue) {
...
// TODO: Load an Interstitial Ad
if (level >= 3 && _interstitialAd == null) {
_loadInterstitialAd();
}
}
- Khi một trò chơi kết thúc, hộp thoại điểm số trò chơi sẽ xuất hiện. Khi người dùng đóng hộp thoại, hộp thoại này sẽ chuyển người dùng đến màn hình chính của Awesome Drawing Quiz.
Vì quảng cáo xen kẽ phải xuất hiện giữa các lần chuyển đổi màn hình, nên chúng tôi sẽ hiển thị quảng cáo xen kẽ khi người dùng nhấp vào nút ĐÓNG.
Sửa đổi phương thức onGameOver() như sau.
lib/game_route.dart
@override
void onGameOver(int correctAnswers) {
showDialog(
context: _scaffoldKey.currentContext,
builder: (context) {
return AlertDialog(
title: Text('Game over!'),
content: Text('Score: $correctAnswers/5'),
actions: [
FlatButton(
child: Text('close'.toUpperCase()),
onPressed: () {
// TODO: Display an Interstitial Ad
if (_interstitialAd != null) {
_interstitialAd?.show();
} else {
_moveToHome();
}
},
),
],
);
},
);
}
- Giải phóng tài nguyên được liên kết với đối tượng
InterstitialAdbằng cách gọi phương thứcInterstitialAd.dispose()trong phương thức gọi lạidispose().
lib/game_route.dart
@override
void dispose() {
...
// TODO: Dispose an InterstitialAd object
_interstitialAd?.dispose();
...
super.dispose();
}
Vậy là xong! Chạy dự án và hoàn thành trò chơi. Nếu quảng cáo xen kẽ được tải, bạn sẽ thấy quảng cáo xen kẽ sau khi nhấp vào nút ĐÓNG trong hộp thoại điểm số.

9. Thêm quảng cáo có tặng thưởng
Trong phần này, bạn sẽ thêm một quảng cáo có tặng thưởng để tặng thêm một gợi ý cho người dùng.
- Mở tệp
lib/game_route.dart - Trong lớp
_GameRouteState, hãy thêm các thành phần cho quảng cáo có tặng thưởng và triển khai phương thức_loadRewardedAd(). Xin lưu ý rằng phương thức này tải một quảng cáo có tặng thưởng khác khi quảng cáo bị đóng (onAdDismissedFullScreenContent) để lưu quảng cáo vào bộ nhớ đệm sớm nhất có thể.
lib/game_route.dart
class _GameRouteState extends State<GameRoute> implements QuizEventListener {
...
// TODO: Add _rewardedAd
RewardedAd? _rewardedAd;
// TODO: Implement _loadRewardedAd()
void _loadRewardedAd() {
RewardedAd.load(
adUnitId: AdHelper.rewardedAdUnitId,
request: AdRequest(),
rewardedAdLoadCallback: RewardedAdLoadCallback(
onAdLoaded: (ad) {
ad.fullScreenContentCallback = FullScreenContentCallback(
onAdDismissedFullScreenContent: (ad) {
setState(() {
ad.dispose();
_rewardedAd = null;
});
_loadRewardedAd();
},
);
setState(() {
_rewardedAd = ad;
});
},
onAdFailedToLoad: (err) {
print('Failed to load a rewarded ad: ${err.message}');
},
),
);
}
...
}
- Gọi
_loadRewardedAd()từ phương thứcinitState()để yêu cầu quảng cáo có tặng thưởng khi trò chơi bắt đầu.
lib/game_route.dart
class _GameRouteState extends State<GameRoute> implements QuizEventListener {
...
@override
void initState() {
...
// COMPLETE: Load a Rewarded Ad
_loadRewardedAd();
}
...
}
- Cho phép người dùng xem quảng cáo có tặng thưởng bằng cách nhấp vào nút hành động nổi. Nút này chỉ xuất hiện nếu người dùng chưa sử dụng gợi ý ở cấp độ hiện tại và quảng cáo có tặng thưởng đã được tải.
Sửa đổi phương thức _buildFloatingActionButton() như sau để hiển thị nút hành động nổi. Xin lưu ý rằng việc trả về null sẽ ẩn nút này khỏi màn hình.
Xin lưu ý rằng onUserEarnedReward là sự kiện quảng cáo quan trọng nhất trong quảng cáo có tặng thưởng. Sự kiện này được kích hoạt khi người dùng đủ điều kiện nhận phần thưởng (ví dụ: xem xong một video).
Trong lớp học lập trình này, phương thức QuizManager.instance.useHint() được gọi từ lệnh gọi lại, cho thấy thêm một ký tự trong chuỗi gợi ý. Ứng dụng tải lại quảng cáo có tặng thưởng trong lệnh gọi lại onAdClosed để đảm bảo quảng cáo sẵn sàng sớm nhất có thể.
lib/game_route.dart
Widget? _buildFloatingActionButton() {
// TODO: Return a FloatingActionButton if a rewarded ad is available
return (!QuizManager.instance.isHintUsed && _rewardedAd != null)
? FloatingActionButton.extended(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Need a hint?'),
content: Text('Watch an Ad to get a hint!'),
actions: [
TextButton(
child: Text('cancel'.toUpperCase()),
onPressed: () {
Navigator.pop(context);
},
),
TextButton(
child: Text('ok'.toUpperCase()),
onPressed: () {
Navigator.pop(context);
_rewardedAd?.show(
onUserEarnedReward: (_, reward) {
QuizManager.instance.useHint();
},
);
},
),
],
);
},
);
},
label: Text('Hint'),
icon: Icon(Icons.card_giftcard),
)
: null;
}
- Giải phóng tài nguyên được liên kết với đối tượng
RewardedAdbằng cách gọi phương thứcRewardedAd.dispose()trong phương thức gọi lạidispose().
lib/game_route.dart
@override
void dispose() {
...
// TODO: Dispose a RewardedAd object
_rewardedAd?.dispose();
...
super.dispose();
}
Vậy là xong! Chạy dự án và chơi trò chơi. Sau khi quảng cáo có tặng thưởng được tải, bạn sẽ thấy một nút gợi ý ở cuối màn hình. Nhấp vào nút Gợi ý để xem gợi ý khác.

10. Đã xong!
Bạn đã hoàn tất lớp học lập trình. Bạn có thể tìm thấy mã hoàn chỉnh cho lớp học lập trình này trong thư mục
complete.
Để tìm hiểu cách triển khai quảng cáo biểu ngữ và quảng cáo gốc trong dòng, hãy xem lớp học lập trình Thêm quảng cáo biểu ngữ và quảng cáo gốc trong dòng của AdMob vào một ứng dụng Flutter.
Để tìm hiểu thêm, hãy thử các lớp học lập trình khác về Flutter.




