ページ遷移のあるアプリの広告実装について

本稿はこの記事の続きです。

いいところ突いてる。
広告で一番事故るのが 「ページ遷移とどう共存させるか」 だからね。
ここを設計として押さえると、一気にプロっぽくなる。

結論から先に言う。

広告は「画面の部品」じゃなくて「遷移のイベント」にぶら下げる。
ページの中にベタ書きすると破綻する。


まず大前提(ここ超重要)

Flutterのページ遷移は、実体としてはこれ。

  • Navigator.push → スタックに画面を積む

  • Navigator.pop → スタックから画面を外す

広告、とくに 全画面広告(Interstitial / Rewarded)
「画面」ではなく 割り込みイベント

だから設計をこう分ける。

  • 画面UI → Widgetツリー

  • 広告 → 遷移の前後で発火する処理


広告の種類ごとの正しい置き場所

バナー広告

これは単純。

  • 各ページの Scaffold の bottomNavigationBar

  • もしくは共通レイアウトに1回だけ

👉 ページ遷移しても一緒に切り替わる

Scaffold(
  body: ...
  bottomNavigationBar: const BannerAdWidget(),
);

インタースティシャル広告(本命)

これは ページ遷移の直前 or 直後

❌ NG例

onPressed: () {
  _showInterstitialAd();
  Navigator.push(...);
}

これ、タイミング競合で壊れやすい。


正解パターン①:遷移前に広告を出す

「次の画面へ行く前に一息入れる」パターン。

onPressed: () async {
  await AdService.instance.showInterstitialIfReady();
  Navigator.push(
    context,
    MaterialPageRoute(builder: (_) => NextPage()),
  );
}

何がいい?

  • 遷移が終わってから広告が被らない

  • UIが壊れにくい

  • iOSでも安定


正解パターン②:遷移後に広告を出す

「画面は切り替えた後に出す」パターン。

Navigator.push(
  context,
  MaterialPageRoute(builder: (_) => NextPage()),
).then((_) {
  AdService.instance.showInterstitialIfReady();
});

使いどころ

  • 一覧 → 詳細

  • 設定 → 戻る


広告ロジックは「サービス」に隔離する

ここが設計の肝。

❌ 画面ごとに広告コードを書く
⭕ 広告専用クラスを1つ作る


AdService(例)

class AdService {
  AdService._();
  static final instance = AdService._();

  InterstitialAd? _interstitialAd;

  void loadInterstitial() {
    InterstitialAd.load(
      adUnitId: InterstitialAd.testAdUnitId,
      request: const AdRequest(),
      adLoadCallback: InterstitialAdLoadCallback(
        onAdLoaded: (ad) {
          _interstitialAd = ad;
        },
        onAdFailedToLoad: (_) {
          _interstitialAd = null;
        },
      ),
    );
  }

  Future<void> showInterstitialIfReady() async {
    if (_interstitialAd == null) return;

    final completer = Completer<void>();

    _interstitialAd!.fullScreenContentCallback =
        FullScreenContentCallback(
      onAdDismissedFullScreenContent: (ad) {
        ad.dispose();
        _interstitialAd = null;
        loadInterstitial();
        completer.complete();
      },
      onAdFailedToShowFullScreenContent: (ad, _) {
        ad.dispose();
        _interstitialAd = null;
        loadInterstitial();
        completer.complete();
      },
    );

    _interstitialAd!.show();
    _interstitialAd = null;

    return completer.future;
  }
}

ポイントを噛み砕くと

  • 広告は「常に1枚だけ管理」

  • 表示できたら破棄

  • 次のために即ロード

  • 画面側は「出せたら出す」だけ


アプリ起動時にやること

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await MobileAds.instance.initialize();
  AdService.instance.loadInterstitial();
  runApp(MyApp());
}

👉
ページは広告の存在を知らない
広告はページ構造を知らない

これが健全。


ページ遷移が多いアプリほど効く設計

あなたのアプリみたいに:

  • 一覧 → 詳細

  • タブ切り替え

  • 戻る操作が多い

こういう構造では、

  • 広告をWidgetとして置く
    → 破綻する

  • 広告を遷移イベントに紐づける
    → 安定する


最後に一言(設計の芯)

広告はUIじゃない。イベントだ。

この認識を持てたら、
ページが増えても、遷移が複雑になっても壊れない。

次に詰まりやすいのは
「戻るボタン(pop)時に広告を出すべきか?」
ここもルールを決めると一気に整理できる。

いいなと思ったら応援しよう!