FlutterでAdMob広告を表示する パート2

以前、「FlutterにAdMob広告を表示する」という記事を書きました。
その後もアプリ組み込みを進めていたところ、実用レベルで組み込むためにはバナー広告周りをもう少し手当しないとダメなことが判明しました。
バナー広告をアプリに組み込む際、全ての画面の同じ位置に表示し続けるのってあんまり現実的じゃありません。「コンテンツを表示するタイプの画面(○○一覧とか○○詳細とか)にはバナーを出すけど編集系画面は出さない」とか「設定画面にだけ出す」とか、何らかの出し分けをするのが一般的です。
ところが、公式プラグインである firebase_admob にはバナー広告を非表示にする方法が用意されていません。また、FlutterのWidgetではないのでFlutterの世界の中で非表示にすることもできません。bannerAd.hide()
みたいなことがしたいのに……。
ということで、表示非表示の制御を自力でやらなくてはならないのです。試行錯誤の過程を箇条書きでまとめてみます。
- 画面遷移を検知する常道はRouteObserverを使うこと
- RouteAwareでは前後の画面が何であるかを知ることはできない(と思う)
- 呼び出し順が直観と違うので、遷移する前後でBannerを表示し続けたいときにうまくいかない
- [Bug?] in didPopNext and didPop call order · Issue #26902 · flutter/flutter
- RouteObserverを継承した独自のクラスを実装し、
didPop
とdidPush
をoverrideしてその中で検知する仕組みにした- 画面遷移のパターンを把握した上でif文で制御することになるので、やり方としてはイマイチ
didPop
やdidPush
の中でbanner表示/非表示を直接処理すると画面遷移が遅くなる- ネイティブ呼び出しているあたりで処理をブロックしてしまう?
- Future.delayで遅延処理するようにした
ということで、RouteObserverの中で気合で制御する形に落ち着きました。これがベスト!とは思わないですが、これ以上にマシなやり方が思いつかず……。
コードはこんな感じです。
class _CustomRouteObserver<R extends Route> extends RouteObserver {
@override
didPop(Route route, Route previousRoute) {
String prevPage = route.settings.name;
String nextPage = previousRoute != null ? previousRoute.settings.name : '';
// prevPage と nextPage で遷移前後のページ名が取れるので
// それをもとにif文でバナーの表示/非表示を制御する
super.didPop(route, previousRoute);
}
@override
didPush(Route route, Route previousRoute) {
String nextPage = route.settings.name;
String prevPage = previousRoute != null ? previousRoute.settings.name : '';
// prevPage と nextPage で遷移前後のページ名が取れるので
// それをもとにif文でバナーの表示/非表示を制御する
super.didPush(route, previousRoute);
}
画面遷移でバナーの表示/非表示を制御できない件についてはfirebase_admobでissueがあがっていますが特にレスポンスなし。
コミット履歴を見ていてもさほど活発に開発されていないようなので、当面はこのままなのかもしれません。
3rd partyなAdMobライブラリもありますが、どれもピンと来ないなあ……。
- duyduong/flutter_native_admob: Plugin to integrate native firebase admob to Flutter application
- YoussefKababe/admob_flutter: Admob Flutter plugin that shows banner ads using native platform views.
いつの日かライブラリがいい感じになることを祈りつつ、当面は今回紹介したやり方でしのごうと思っています。
関連(するかもしれない)記事
おススメ