google_mobile_ads_async 1.0.0 copy "google_mobile_ads_async: ^1.0.0" to clipboard
google_mobile_ads_async: ^1.0.0 copied to clipboard

A powerful, async-first wrapper for the official google_mobile_ads package. Load ads with Futures, implement ad waterfalls, use declarative widgets, and leverage a built-in cache.

example/lib/main.dart

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

// Ad Unit IDs for testing. Replace with your own in production.
const String bannerAdUnitId = 'ca-app-pub-3940256099942544/6300978111';
const String interstitialAdUnitId = 'ca-app-pub-3940256099942544/1033173712';
const String rewardedAdUnitId = 'ca-app-pub-3940256099942544/5224354917';
const String nativeAdUnitId = 'ca-app-pub-3940256099942544/2247696110';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // --- Example Log Configuration ---
  // Set the log level to see detailed messages during debugging.
  // Use Level.verbose for the most detail.
  GoogleMobileAdsAsync.setLogLevel(Level.debug);

  // Initialize the Google Mobile Ads SDK.
  await MobileAds.instance.initialize();
  // Preload ads using the cache manager.
  await _preloadAds();
  runApp(const MyApp());
}

Future<void> _preloadAds() async {
  final cacheManager = AdCacheManager.instance;
  // Preload multiple ads in parallel.
  await Future.wait([
    cacheManager.preloadAd(
      adUnitIds: [interstitialAdUnitId],
      type: AdType.interstitial,
    ),
    cacheManager.preloadAd(
      adUnitIds: [rewardedAdUnitId],
      type: AdType.rewarded,
    ),
    // Preload a banner for the bottom navigation bar.
    cacheManager.preloadAd(
      adUnitIds: [bannerAdUnitId],
      type: AdType.banner,
      size: AdSize.mediumRectangle,
    ),
  ]);
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Google Mobile Ads Async Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        elevatedButtonTheme: ElevatedButtonThemeData(
          style: ElevatedButton.styleFrom(
            minimumSize: const Size(250, 50),
            textStyle: const TextStyle(fontSize: 18),
          ),
        ),
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // --- Ad Showing Methods ---

  void _showInterstitialAd() {
    // Get the ad from the cache.
    final ad = AdCacheManager.instance.getAd<InterstitialAd>([
      interstitialAdUnitId,
    ]);

    if (ad != null) {
      ad.show();
      // Preload the next one.
      AdCacheManager.instance.preloadAd(
        adUnitIds: [interstitialAdUnitId],
        type: AdType.interstitial,
      );
    } else {
      _showSnackBar('Interstitial ad is not ready yet.');
      // Optionally, load the ad if it wasn't in the cache.
      AdCacheManager.instance.preloadAd(
        adUnitIds: [interstitialAdUnitId],
        type: AdType.interstitial,
      );
    }
  }

  void _showRewardedAd() {
    // Get the ad from the cache.
    final ad = AdCacheManager.instance.getAd<RewardedAd>([rewardedAdUnitId]);

    if (ad != null) {
      ad.show(
        onUserEarnedReward: (ad, reward) {
          _showSnackBar('Reward earned: ${reward.amount} ${reward.type}');
        },
      );
      // Preload the next one.
      AdCacheManager.instance.preloadAd(
        adUnitIds: [rewardedAdUnitId],
        type: AdType.rewarded,
      );
    } else {
      _showSnackBar('Rewarded ad is not ready yet.');
      // Optionally, load the ad if it wasn't in the cache.
      AdCacheManager.instance.preloadAd(
        adUnitIds: [rewardedAdUnitId],
        type: AdType.rewarded,
      );
    }
  }

  void _showSnackBar(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(message)),
    );
  }

  @override
  Widget build(BuildContext context) {
    GoogleMobileAdsAsync.isAdsEnabled = false;
    // Try to get the cached banner ad.
    final cachedBanner =
        AdCacheManager.instance.getAd<BannerAd>([bannerAdUnitId]);

    return Scaffold(
      appBar: AppBar(
        title: const Text('Ad Demo'),
      ),
      body: SizedBox.expand(
        child: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const SizedBox(height: 20),
              const Text(
                'Cached Ads (Programmatic)',
                style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 20),
              ElevatedButton(
                onPressed: _showInterstitialAd,
                child: const Text('Show Interstitial Ad'),
              ),
              const SizedBox(height: 20),
              ElevatedButton(
                onPressed: _showRewardedAd,
                child: const Text('Show Rewarded Ad'),
              ),
              const SizedBox(height: 40),
              const Text(
                'Widget-Based Ads',
                style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 20),
              const Text('Native Ad', style: TextStyle(fontSize: 18)),
              const SizedBox(height: 10),
              NativeAdWidget(
                // The widget will load the ad using the adUnitIds.
                adUnitIds: const [nativeAdUnitId],
                loadingBuilder: (_) =>
                    const Center(child: CircularProgressIndicator()),
                nativeTemplateStyle: NativeTemplateStyle(
                  templateType: TemplateType.medium,
                  cornerRadius: 12,
                  mainBackgroundColor: Colors.grey.shade200,
                ),
              ),
              const SizedBox(height: 20),
              const Text('Banner Ad (in-line)', style: TextStyle(fontSize: 18)),
              const SizedBox(height: 10),
              BannerAdWidget(
                adUnitIds: const [bannerAdUnitId],
                sizeConfig:
                    const BannerAdSizeConfig.standard(AdSize.mediumRectangle),
                loadingBuilder: (_) =>
                    const Center(child: CircularProgressIndicator()),
              ),
              const SizedBox(height: 20),
              const Text(
                'Inline Adaptive Banner',
                style: TextStyle(fontSize: 18),
              ),
              const SizedBox(height: 10),
              BannerAdWidget(
                adUnitIds: const [bannerAdUnitId],
                sizeConfig: const BannerAdSizeConfig.inline(
                  padding: EdgeInsets.symmetric(horizontal: 16),
                ),
                loadingBuilder: (_) =>
                    const Center(child: CircularProgressIndicator()),
              ),
              const SizedBox(height: 20),
            ],
          ),
        ),
      ),
      // The widget will display the cached ad if available,
      // otherwise it will load a new one using the adUnitId.
      bottomNavigationBar: BannerAdWidget(
        ad: cachedBanner,
        adUnitIds: const [bannerAdUnitId],
        sizeConfig: const BannerAdSizeConfig.anchored(),
      ),
    );
  }

  @override
  void dispose() {
    // Dispose all cached ads when the app is closed.
    AdCacheManager.instance.disposeAllAds();
    super.dispose();
  }
}
2
likes
150
points
183
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A powerful, async-first wrapper for the official google_mobile_ads package. Load ads with Futures, implement ad waterfalls, use declarative widgets, and leverage a built-in cache.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, google_mobile_ads, logger

More

Packages that depend on google_mobile_ads_async