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

2019/05/30

以前、「FlutterにAdMob広告を表示する」という記事を書きました。

その後もアプリ組み込みを進めていたところ、実用レベルで組み込むためにはバナー広告周りをもう少し手当しないとダメなことが判明しました。

バナー広告をアプリに組み込む際、全ての画面の同じ位置に表示し続けるのってあんまり現実的じゃありません。「コンテンツを表示するタイプの画面(○○一覧とか○○詳細とか)にはバナーを出すけど編集系画面は出さない」とか「設定画面にだけ出す」とか、何らかの出し分けをするのが一般的です。

ところが、公式プラグインである firebase_admob にはバナー広告を非表示にする方法が用意されていません。また、FlutterのWidgetではないのでFlutterの世界の中で非表示にすることもできません。bannerAd.hide() みたいなことがしたいのに……。

ということで、表示非表示の制御を自力でやらなくてはならないのです。試行錯誤の過程を箇条書きでまとめてみます。

  • 画面遷移を検知する常道はRouteObserverを使うこと
  • RouteAwareでは前後の画面が何であるかを知ることはできない(と思う)
  • RouteObserverを継承した独自のクラスを実装し、didPopdidPushをoverrideしてその中で検知する仕組みにした
    • 画面遷移のパターンを把握した上でif文で制御することになるので、やり方としてはイマイチ
  • didPopdidPushの中で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ライブラリもありますが、どれもピンと来ないなあ……。

いつの日かライブラリがいい感じになることを祈りつつ、当面は今回紹介したやり方でしのごうと思っています。




関連(するかもしれない)記事


おススメ