You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何实现用户看完激励广告后跳转至第二内容页面

Flutter激励广告跳转页面实现方案

1. 所需依赖

使用谷歌官方的移动广告SDK google_mobile_ads,在pubspec.yaml中添加依赖即可:

dependencies:
  flutter:
    sdk: flutter
  google_mobile_ads: ^3.1.0

2. 核心实现逻辑

  • 应用启动时先初始化广告SDK
  • 进入首页后预加载激励视频广告,避免用户点击按钮后等待
  • 按钮点击时校验广告是否加载完成,已加载则直接展示,未加载展示加载中提示
  • 监听广告生命周期回调:
    • 用户完成广告观看获得奖励时,标记授权状态为允许跳转,同时弹出手动跳转确认弹窗
    • 用户关闭广告时,若已获得奖励则直接自动跳转至第二页面
    • 广告加载/播放失败时给用户对应提示
  • 广告播放完成后,支持两种跳转触发方式:手动点击确认弹窗的确认按钮、点击广告关闭按钮自动跳转

3. 完整实现代码

首先在端侧配置文件中添加广告ID配置,以下为官方测试ID,正式上线替换为自己申请的正式ID即可:

安卓端在android/app/src/main/AndroidManifest.xml的application标签内添加:

<meta-data
    android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="ca-app-pub-3940256099942544~3347511713"/>

iOS端在ios/Runner/Info.plist的dict标签内添加:

<key>GADApplicationIdentifier</key>
<string>ca-app-pub-3940256099942544~1458002511</string>

Dart业务代码如下:

import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

// 测试用激励广告ID,正式环境替换为自己的广告ID
const String _testRewardedAdUnitId = 'ca-app-pub-3940256099942544/5224354917';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 初始化广告SDK
  await MobileAds.instance.initialize();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '激励广告跳转演示',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const FirstPage(),
    );
  }
}

class FirstPage extends StatefulWidget {
  const FirstPage({super.key});

  @override
  State<FirstPage> createState() => _FirstPageState();
}

class _FirstPageState extends State<FirstPage> {
  RewardedAd? _rewardedAd;
  bool _hasEarnedReward = false;
  bool _isAdLoading = false;

  @override
  void initState() {
    super.initState();
    // 进入页面后预加载广告
    _loadRewardedAd();
  }

  // 加载激励广告
  void _loadRewardedAd() {
    setState(() => _isAdLoading = true);
    RewardedAd.load(
      adUnitId: _testRewardedAdUnitId,
      request: const AdRequest(),
      rewardedAdLoadCallback: RewardedAdLoadCallback(
        onAdLoaded: (ad) {
          _rewardedAd = ad;
          _setAdCallbacks(ad);
          setState(() => _isAdLoading = false);
        },
        onAdFailedToLoad: (error) {
          _rewardedAd = null;
          setState(() => _isAdLoading = false);
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('广告加载失败,请稍后重试')),
          );
        },
      ),
    );
  }

  // 设置广告回调监听
  void _setAdCallbacks(RewardedAd ad) {
    ad.fullScreenContentCallback = FullScreenContentCallback(
      // 广告展示成功
      onAdShowedFullScreenContent: (ad) => _hasEarnedReward = false,
      // 广告关闭
      onAdDismissedFullScreenContent: (ad) {
        ad.dispose();
        _rewardedAd = null;
        // 关闭广告时如果已经获得奖励,直接跳转
        if (_hasEarnedReward) {
          _navigateToSecondPage();
        }
        // 重新预加载下一次广告
        _loadRewardedAd();
      },
      // 广告播放失败
      onAdFailedToShowFullScreenContent: (ad, error) {
        ad.dispose();
        _rewardedAd = null;
        _loadRewardedAd();
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('广告播放失败,请稍后重试')),
        );
      },
    );
  }

  // 展示广告
  void _showRewardedAd() {
    if (_rewardedAd == null) {
      if (_isAdLoading) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('广告加载中,请稍候')),
        );
      } else {
        _loadRewardedAd();
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('广告未准备好,正在重新加载')),
        );
      }
      return;
    }

    // 广告播放完成获得奖励的回调
    _rewardedAd!.show(
      onUserEarnedReward: (ad, reward) {
        _hasEarnedReward = true;
        // 弹出手动跳转确认框
        showDialog(
          context: context,
          builder: (context) => AlertDialog(
            title: const Text('广告观看完成'),
            content: const Text('是否立即进入目标页面?'),
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(context),
                child: const Text('稍后'),
              ),
              TextButton(
                onPressed: () {
                  Navigator.pop(context);
                  _navigateToSecondPage();
                },
                child: const Text('立即进入'),
              ),
            ],
          ),
        );
      },
    );
  }

  // 跳转至第二页面
  void _navigateToSecondPage() {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => const SecondPage()),
    );
  }

  @override
  void dispose() {
    _rewardedAd?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('首页')),
      body: Center(
        child: ElevatedButton(
          onPressed: _showRewardedAd,
          child: const Text('进入目标页面'),
        ),
      ),
    );
  }
}

// 目标第二页面
class SecondPage extends StatelessWidget {
  const SecondPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('目标页面')),
      body: const Center(child: Text('这是需要看完广告才能进入的第二页面')),
    );
  }
}

4. 注意事项

  • 测试阶段必须使用官方提供的测试广告ID,否则会被判定为违规
  • 正式上线前需要替换为自己在AdMob后台申请的对应平台的广告ID
  • 代码中默认会在广告关闭后自动预加载下一次广告,优化后续点击的加载速度
  • 若不需要手动跳转确认弹窗,直接删除onUserEarnedReward中的弹窗逻辑即可,仅保留关闭广告自动跳转的逻辑

内容的提问来源于stack exchange,提问作者misterkonna24

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 11:48:04