1

I have flutter project and I added one banner admob in screen but I need to load more one in the same screen , I try to repeat call the function in different place

    ======== Exception caught by widgets library =======================================================
The following assertion was thrown building AdWidget(dirty, state: _AdWidgetState#72c34):
This AdWidget is already in the Widget tree


If you placed this AdWidget in a list, make sure you create a new instance in the builder function with a unique ad object.
Make sure you are not using the same ad object in more than one AdWidget.

Can I load more than one banner in same screen ?

this is a link on Github https://github.com/Hussamedeen/MyDealApp

HomeScreen.dart

Hussamedeen
  • 11
  • 1
  • 4

3 Answers3

1

Since you've not provided any code, I'd assume and answer based on how I think you can do it.

If you're displaying the ad in predefined fixed locations, you'd need to create a new BannerAd for each location. You'd also have to individually load these BannerAds like so:

final BannerAd myBanner1 = BannerAd(
  adUnitId: '<Banner ID>',
  size: AdSize.smartBanner,
  request: AdRequest(),
  listener: AdListener(onAdClosed: (ad) => ad.dispose()),
);
myBanner1.load();
final adWidget1 = AdWidget(ad: myBanner1);
...
...
...
final BannerAd myBannerNth = BannerAd(
  adUnitId: '<Banner ID>',
  size: AdSize.banner,
  request: AdRequest(),
  listener: AdListener(onAdClosed: (ad) => ad.dispose()),
);
myBannerNth.load();
final adWidgetNth = AdWidget(ad: myBannerNth);

Where myBannerNth/adWidgetNth is the nth banner/ad widget.

For dynamic, auto-generated situations such as in a ListView.separated, you could do it like so:

// Defined somewhere, e.g. in your State[less/ful] widget
Map<String, BannerAd> ads = <String, BannerAd>{}; 
...
...
...

ListView.separated(
  separatorBuilder: (context, index) => Divider(),
  shrinkWrap: true,
  itemBuilder: (BuildContext context, int index) {
    ads['myBanner$index'] = BannerAd(
      adUnitId: '<Banner ID>',
      size: AdSize.banner,
      request: AdRequest(),
      listener: AdListener(onAdClosed: (ad) => ad.dispose()));
    ads['myBanner$index'].load();

    if (index % 6 == 0) {
      return Column(
        children: [
          Container(
            child: AdWidget(ad: ads['myBanner$index']),
            height: 100.0,
          ),
         _buildItem(context, items[index])
       ],
     );
   }
   return _buildItem(context, items[index]);
  },
  itemCount: items.length,
)

Where ads is a Map whose values are the individual dynamically auto-generated banner ads.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Nayi
  • 65
  • 1
  • 10
  • Is 1 bannerId sufficient for multiple banners? Or do I need different bannerId's depending on the number of banners I'm showing? – Wilfred Almeida Jul 02 '22 at 05:18
  • @WilfredAlmeida you can use one banner ID for all banners as in the second example. Or you can use multiple banner IDs like in the first example. – Nayi Jul 03 '22 at 07:22
1

You can use this function to show multiple Ads:

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

class AppAds {
  static bannerAds(BuildContext context) {
    return Builder(builder: (ctx) {
      final BannerAd myBanner = BannerAd(
        adUnitId: 'ca-app-pub-3940256099942544/6300978111',
        request: const AdRequest(),
        listener: const BannerAdListener(),
        size: AdSize.banner,
      );
      myBanner.load();
      return Container(
        alignment: Alignment.center,
        width: myBanner.size.width.toDouble(),
        height: myBanner.size.height.toDouble(),
        child: AdWidget(
          ad: myBanner,
          key: Key(myBanner.hashCode.toString()),
        ),
      );
    });
  }
}
Bholendra Singh
  • 980
  • 7
  • 14
0

SOURCE:

https://github.com/googleads/googleads-mobile-flutter/issues/36

There are other ways to do it for example creating another stateful class like in the package's example folder.

static Future getBannerWidget( {@required BuildContext context, AdSize adSize, }) async{

BannerAd bannerAd = BannerAd(
  adUnitId: getBannerAdUnitId(),
  size: adSize ?? AdSize.smartBanner,
  request: _adRequest,
  listener: AdListener(
    // Called when an ad is successfully received.
    onAdLoaded: (Ad ad) {

      if(_debug){
        print('Ad loaded.');
      }

    },
    // Called when an ad request failed.
    onAdFailedToLoad: (Ad ad, LoadAdError error) {

      if(_debug){
        print('Ad failed to load: $error');
        //_bannerAd.dispose();
      }

    },
    // Called when an ad opens an overlay that covers the screen.
    onAdOpened: (Ad ad) {

      if(_debug){
        print('Ad opened.');
      }

    },
    // Called when an ad removes an overlay that covers the screen.
    onAdClosed: (Ad ad) {

      if(_debug){
        print('Ad closed.');
      }

    },
    // Called when an ad is in the process of leaving the application.
    onApplicationExit: (Ad ad) {

      if(_debug){
        print('Left application.');
      }

    },
  ),
);

await bannerAd.load();

return Container(
    child: AdWidget(ad: bannerAd),
    constraints: BoxConstraints(
      maxHeight: 90,
      maxWidth: MediaQuery.of(context).size.width,
      minHeight: 32,
      minWidth: MediaQuery.of(context).size.width,
    ),
);

}

In the screen:

   FutureBuilder<Widget>(
            future: Ads.getBannerWidget(
                context: context,
                adSize: AdSize.leaderboard
            ),
            builder: (_, snapshot){

              if(!snapshot.hasData){

                return Text("Loading Ad...");

              } else {

                return Container(
                  height: 90,
                  width: MediaQuery.of(context).size.width,
                  child: snapshot.data,
                );

              }

            },
          ),
Steven Ogwal
  • 685
  • 6
  • 8