Home > Blockchain >  Flutter Ads Causing Delay
Flutter Ads Causing Delay

Time:08-27

I recently ported my flutter app from admob_flutter to google_mobile_ads. I've successfully implemented banner ads according to the tutorial here. The ads appear as expected however they cause the rest of the app to wait for them to load, as if something is being awaited. Here is a visual of the problem:

no banner (expected behaviour)

with banner (buggy)

The delay is even worse when I want to load pages with more than a couple widgets. At first I thought this was because the app is being run on an emulator, however the phenomenon persists on physical phones with updated OSes as well. I found this issue and thought it might be related however using the suggested package didn't work, and again the problem occurs on updated versions of android as well ( > 10). Here is my Ad class:

class AnchoredAdaptiveBanner extends StatefulWidget {
  @override
  _AnchoredAdaptiveBannerState createState() => _AnchoredAdaptiveBannerState();
}

class _AnchoredAdaptiveBannerState extends State<AnchoredAdaptiveBanner> {
  BannerAd _anchoredAdaptiveAd;
  bool _isLoaded = false;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _loadAd();
  }

  Future<void> _loadAd() async {
    // This was originally dynamic with an await, I changed it to static values for a sanity check, again same problem.
    final AnchoredAdaptiveBannerAdSize size = AnchoredAdaptiveBannerAdSize(Orientation.portrait, width: 300, height: 50);

    _anchoredAdaptiveAd = BannerAd(
      adUnitId: AdManager.bannerAdUnitId,
      size: size,
      request: AdRequest(),
      listener: BannerAdListener(
        onAdLoaded: (Ad ad) {
          setState(() {
            _anchoredAdaptiveAd = ad as BannerAd;
            _isLoaded = true;
          });
        },
        onAdFailedToLoad: (Ad ad, LoadAdError error) {
          ad.dispose();
        },
      ),
    );
    return _anchoredAdaptiveAd.load();
  }

  @override
  Widget build(BuildContext context) {
    if (_anchoredAdaptiveAd != null && _isLoaded)
      return Container(
        width: _anchoredAdaptiveAd.size.width.toDouble(),
        height: _anchoredAdaptiveAd.size.height.toDouble(),
        child: AdWidget(ad: _anchoredAdaptiveAd),
      );
    else
      return Container();
  }

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

My usage in my home widget for example:

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: SafeArea(
        child: Scaffold(
          body: Builder(...),
          floatingActionButton: Container(...),
         bottomNavigationBar: AnchoredAdaptiveBanner()
        ),
      ),
    );
  }
}

As you can see nothing is being top-level awaited. I am currently on version 2.0.1 of google_mobile_ads. Any idea what is causing this? Any help is appreciated!

CodePudding user response:

The solution: Return SizedBox.shrink()

Why does this work?

Until the ad is loaded you're returning an empty container from your build method. If you don't pass height or width to the container, it expands as much as possible. In this case bottomNavigationBars can expand infinitely. This causes the rest of the widgets to be pushed out of screen and the page seems frozen until the ad loads. Using SizedBox.shrink() will have the container be 0x0 until it loads.

  • Related