【Flutter × AdMob】ListView内でバナー広告を表示する
現在「ねこバズ」という「ネコ関連のバズツイートだけが流れてくるアプリ」を開発中です。
- どうせ作るなら広告入れてみたい
- でも「画面上下部に固定されるタイプの広告」はちょっと抵抗がある
という理由から ListView 内で表示できるバナー広告を実装しました。
Flutter の AdMob パッケージ
Flutter で用意されている admob パッケージは大きく 3 つあります。
- firebase_admob
Firebase が用意しているパッケージ。
広告を Widget 扱いすることができず、画面上部・下部に固定されてしまう。
2021 年 8 月 2 日現在では DISCONTINUED となっており、今後の積極的な開発は期待できない。
- admob_flutter
OSS で作られているパッケージ。
広告をひとつの Widget として扱うことができるので、好きな場所に広告を実装することができる。
コントリビューター不足で、あまり積極的に開発が行われていない。
- google_mobile_ads
2021 年 2 月に Google が出したパッケージ。
広告を Widget として扱うことができ、かつ開発も積極的に行われている。
FlutterDeveloper 待望のパッケージ。
今回は、3 つ目の google_mobile_ads を使った広告実装についてまとめていきます。
前提
- Flutter 1.22.0 以上
- アプリ未リリース
実装手順
- AdMob の登録
- パッケージの導入
- iOS/Android での設定
- 広告の実装
0. AdMob の登録
上記にアクセスし、必要事項を記入します。
AdMob のユーザー登録が完了しました。
iOS アプリの設定
サイドバーの「アプリ」→「アプリを登録して利用を開始」
まずは iOS から登録します。
アプリ名(bundleId とかじゃなくなんでもいい)とユーザー指標にチェックを入れて「アプリを追加」
iOS アプリが追加されました。
Android アプリの設定
「アプリを追加」から Android アプリの設定も同様に行います。
ここで Android を選択します。それ以外は同じです。
iOS、Android 両方のアプリが作成できました。
アプリ ID の確認
「アプリ」→「すべてのアプリを表示」で
それぞれのアプリ ID を確認することができます。
広告ユニットの作成
次に、広告ユニットを作成します。
サイドバーの「アプリ」→「広告ユニット」
様々な広告フォーマットがありますが、今回は ListView 内に広告を挿入したいので、「バナー」を選択
広告ユニット名を記入します。
広告ユニットが作成され、ID が生成されました。
アプリ ID と混同しそうですが、別物です。
アプリID・・・それぞれのアプリに一つだけ存在
広告ユニットID・・・作成した広告ごとに存在(複数生成できる)
iOS アプリの AdMob 登録ができました。
Android アプリでも同様に広告ユニットを生成しておきましょう。
1. パッケージ導入
Flutter で実装していきます。以下のパッケージを pubspec.yaml に追加し、pub get します。
dependencies:
flutter:
sdk: flutter
・
・
・
google_mobile_ads: ^0.13.2+1
2. iOS/Android での設定
iOS は、ios/Runner/Info.plist を以下のように更新します。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
~~~~~~~~~
<key>GADApplicationIdentifier</key>
<string>iOSアプリID</string>
<key>SKAdNetworkItems</key>
<array>
<dict>
<key>SKAdNetworkIdentifier</key>
<string>cstr6suwn9.skadnetwork</string>
</dict>
</array>
~~~~~~~~~
</dict>
</plist>
Android は、android/app/src/main/AndroidManifest.xml 内を以下のように更新します。
<manifest xmlns:android=""
package="">
<application
android:label=""
android:icon="">
<!-- Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713 -->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="AndroidのアプリID"/>
</application>
</manifest>
3. 広告の実装
パッケージの初期化
まずは main 関数内で、初期化処理を行います。
void main() {
WidgetsFlutterBinding.ensureInitialized();
MobileAds.instance.initialize(); // 追加
runApp(const MyApp());
}
広告の初期化(バナー広告)
次に、広告ウィジェットの初期化です。
BannerAd クラスをインスタンス化した後、.load();メソッドを呼び出すことでバナー広告を読み込みます。
// バナー広告をインスタンス化
BannerAd myBanner = BannerAd(
adUnitId: getTestAdBannerUnitId(),
size: AdSize.banner,
request: const AdRequest(),
listener: const BannerAdListener();
);
// バナー広告の読み込み
myBanner.load();
getTestAdBannerUnitId()
は、プラットフォーム(iOS/Android)に合わせてデモ用広告 ID を返します。
// プラットフォーム(iOS / Android)に合わせてデモ用広告IDを返す
String getTestAdBannerUnitId() {
String testBannerUnitId = "";
if (Platform.isAndroid) {
// Android のとき
testBannerUnitId = "ca-app-pub-3940256099942544/6300978111"; // Androidのデモ用バナー広告ID
} else if (Platform.isIOS) {
// iOSのとき
testBannerUnitId = "ca-app-pub-3940256099942544/2934735716"; // iOSのデモ用バナー広告ID
}
return testBannerUnitId;
}
テストモードを使わずに多くの広告をクリックすると、無効なアクティビティとしてアカウントが警告を受ける恐れがあります。
開発時には、必ずデモ用の広告ユニットを使うようにしましょう。
広告の種類 | iOS | Android |
---|---|---|
バナー | ca-app-pub-3940256099942544/2934735716 | ca-app-pub-3940256099942544/6300978111 |
リワード | ca-app-pub-3940256099942544/1712485313 | ca-app-pub-3940256099942544/5224354917 |
ネイティブ アドバンス | ca-app-pub-3940256099942544/3986624511 | ca-app-pub-3940256099942544/2247696110 |
上記以外のデモ用広告 ID は以下で確認できます。
- iOS
- Android
バナー広告 Widet を使って表示
load()
を呼び出した後、AdWidget
を用いることで、広告を表示することができます。
AdWidget
は StatefulWidget を継承しており、他の Widget たちと同様に UI に組み込むことが可能です。
AdWidget(ad: myBanner),
バナー広告の表示が出来ました。
ListView 内に広告を挿入
最後に、 ListView 内に広告を挿入する例を紹介しておきます。
ListView.builder の index が 5 の倍数のときに広告を挿入する
というコードにしてみました。
/// リスト表示部分
child: ListView.builder(
itemCount: tweets.length,
itemBuilder: (context, index) {
final tweet = tweets[index];
return Column(
children: [
// indexが 5 の倍数の場合
index % 5 == 0
? Container(
color: Colors.white,
height: 64.0,
width: double.infinity,
child: AdWidget(ad: myBanner),
)
: const SizedBox(),
// ツイート部分
InkWell(
onTap: () async {
await Navigator.push<dynamic>(
context,
MaterialPageRoute<dynamic>(
builder: (context) =>
TweetDetailPage(tweet),
),
);
},
child: TweetCardWidget(
tweet: tweet,
tag: kTimeLineHeroTag,
),
),
],
);
},
),
バナー広告をリスト内に挿入することができました。
よくある「バナーが画面上部や下部に固定されているヤツ」に比べると、ユーザーへのストレスも多少は軽減されるのではないでしょうか。
これから AdMob の実装する方の参考になれば幸いです。
最後まで読んでいただき、ありがとうございました。
参考
- google_mobile_ads
- Google AdMob スタートガイド
- Google Mobile Ads for Flutter の最新 0.13.0 使ってみた
Discussion