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

Flutter中实现全局持久化底部导航栏谷歌横幅广告方案

实现全局持久化底部横幅广告方案

针对你的需求,我们可以通过GetX全局控制器+App全局构建拦截的方式,只实现一次广告逻辑,让所有页面自动带上底部横幅广告,无需重复代码。

步骤1:创建全局广告控制器

编写一个GetX控制器,统一管理BannerAd的加载、状态和生命周期,确保整个App只有一个广告实例:

import 'package:get/get.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

class BannerAdController extends GetxController {
  late BannerAd _bannerAd;
  final RxBool isAdLoaded = false.obs;
  // 替换成你的广告单元ID
  final String adUnitId = bannerKey;

  @override
  void onInit() {
    super.onInit();
    _loadBannerAd();
  }

  void _loadBannerAd() {
    _bannerAd = BannerAd(
      adUnitId: adUnitId,
      size: AdSize.banner,
      request: const AdRequest(),
      listener: BannerAdListener(
        onAdLoaded: (ad) => isAdLoaded.value = true,
        onAdFailedToLoad: (ad, error) {
          ad.dispose();
          // 加载失败自动重试,可根据需求调整延迟时间
          Future.delayed(const Duration(seconds: 5), _loadBannerAd);
        },
        onAdClosed: (ad) {
          isAdLoaded.value = false;
          ad.dispose();
          _loadBannerAd(); // 广告关闭后重新加载
        },
      ),
    );
    _bannerAd.load();
  }

  BannerAd get bannerAd => _bannerAd;

  @override
  void onClose() {
    _bannerAd.dispose();
    super.onClose();
  }
}

步骤2:修改全局App入口,注入广告并全局渲染

在MyApp中初始化广告控制器,并通过builder拦截所有页面的构建,将底部广告全局添加到所有页面下方:

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static final GlobalKey<NavigatorState> navigatorKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    // 全局注入广告控制器,单例模式
    Get.put(BannerAdController());
    
    return GetMaterialApp(
      navigatorKey: navigatorKey,
      defaultTransition: Transition.rightToLeftWithFade,
      initialRoute: '/',
      getPages: AppRoutes.pages(),
      debugShowCheckedModeBanner: false,
      builder: (context, child) {
        final bannerController = Get.find<BannerAdController>();
        
        return Column(
          children: [
            // 页面主体内容占满剩余空间
            Expanded(child: child!),
            // 响应式渲染底部广告
            Obx(() {
              return bannerController.isAdLoaded.value
                  ? SizedBox(
                      height: bannerController.bannerAd.size.height.toDouble(),
                      width: bannerController.bannerAd.size.width.toDouble(),
                      child: AdWidget(ad: bannerController.bannerAd),
                    )
                  : const SizedBox.shrink();
            }),
          ],
        );
      },
    );
  }
}

步骤3:移除页面内重复代码

现在所有页面都会自动显示底部广告,把之前页面(比如ProgrammeScreen)中的广告相关重复代码全部删除:

  • _bottomBannerAd1变量
  • _isBottomBannerLoaded变量
  • createBottomBannerAd方法
  • initState和dispose中的广告逻辑
  • build方法里的bottomNavigationBar参数

核心优势

  • 全局唯一广告实例,避免重复创建销毁,节省资源
  • 所有页面自动继承底部广告,无需重复编写代码
  • GetX响应式状态管理,广告状态变化自动更新UI
  • 统一处理广告失败重试、关闭重加载等逻辑,维护更方便

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 08:09:18