【问题标题】:How to show multiple google native ad in flutter如何在颤动中显示多个谷歌原生广告
【发布时间】:2021-03-29 08:49:21
【问题描述】:

我正在尝试在 listview 中动态调用 广告,但会引发此错误:

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. 

这里是代码

导入包google_mobile_ads

import 'package:google_mobile_ads/google_mobile_ads.dart';

然后实例化包

NativeAd _nativeAd;

final Completer<NativeAd> nativeAdCompleter = Completer<NativeAd>();

我的功能是加载广告

loadAd(){
    _nativeAd = NativeAd(
      adUnitId: "ca-app-pub-3940256099942544/1044960115",
      request: AdRequest(),
      factoryId: 'adFactoryExample',
      listener: AdListener(
        onAdLoaded: (Ad ad) {
          print('$NativeAd loaded.');
          nativeAdCompleter.complete(ad as NativeAd);
        },
        onAdFailedToLoad: (Ad ad, LoadAdError error) {
          ad.dispose();
          print('$NativeAd failedToLoad: $error');
          nativeAdCompleter.completeError(null);
        },
        onAdOpened: (Ad ad) => print('$NativeAd onAdOpened.'),
        onAdClosed: (Ad ad) => print('$NativeAd onAdClosed.'),
        onApplicationExit: (Ad ad) => print('$NativeAd onApplicationExit.'),
      ),
    );
    Future<void>.delayed(Duration(seconds: 1), () => _nativeAd?.load());
  }

然后为了显示添加,我在 switch case 语句中执行了此操作

case 'ad':
                                  loadAd();

                                  return FutureBuilder<NativeAd>(
                                    future: nativeAdCompleter.future,
                                    builder: (BuildContext context, AsyncSnapshot<NativeAd> snapshot) {
                                      Widget child;

                                      switch (snapshot.connectionState) {
                                        case ConnectionState.none:
                                        case ConnectionState.waiting:
                                        case ConnectionState.active:
                                          child = Container();
                                          break;
                                        case ConnectionState.done:
                                          if (snapshot.hasData) {
                                            child = AdWidget(ad: _nativeAd);
                                          } else {
                                            child = Text('Error loading $NativeAd');
                                          }
                                      }

                                      return Scaffold(
                                        body: Container(
                                          width: double.infinity,
                                          height: double.infinity,
                                          margin: EdgeInsets.only(top: 100, left: 5, right: 5, bottom: 70),
                                          child: Center(child: child),
                                          color: Colors.black,
                                        ),
                                      );
                                    },
                                  );
                                  break;

此集成在显示来自第二个广告的广告时引发上述异常

【问题讨论】:

  • 答案不是错误..

标签: flutter admob googlemobileads


【解决方案1】:

我真的不确定你是如何实现这个小部件的,因为你只显示了你类的一部分,但我相信如果你为原生广告制作了独立的小部件并将 NativeAd 的初始化放在 initState 中,它应该可以工作像这样。

然后您可以在列表视图中使用NativeAdWidget

class NativeAdWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => NativeAdState();
}

class NativeAdState extends State<NativeAdWidget> {
  NativeAd _nativeAd;
  final Completer<NativeAd> nativeAdCompleter = Completer<NativeAd>();

  @override
  void initState() {
    super.initState();

    _nativeAd = NativeAd(
      adUnitId: Platform.isAndroid ? getIt<Vars>().androidNativeId : getIt<Vars>().iosNativeId,
      request: const AdRequest(nonPersonalizedAds: true),
      customOptions: <String, Object>{},
      factoryId: getIt<Vars>().admobFactoryId,
      listener: AdListener(
        onAdLoaded: (Ad ad) {
          nativeAdCompleter.complete(ad as NativeAd);
        },
        onAdFailedToLoad: (Ad ad, LoadAdError err) {
          unawaited(HandleError.logError(err.message));
          ad.dispose();
          nativeAdCompleter.completeError(null);
        },
        onAdOpened: (Ad ad) => print('$ad onAdOpened.'),
        onAdClosed: (Ad ad) => print('$ad onAdClosed.'),
        onApplicationExit: (Ad ad) => print('$ad onApplicationExit.'),
      ),
    );

    _nativeAd?.load();
  }

  @override
  void dispose() {
    super.dispose();
    _nativeAd?.dispose();
    _nativeAd = null;
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<NativeAd>(
      future: nativeAdCompleter.future,
      builder: (BuildContext context, AsyncSnapshot<NativeAd> snapshot) {
        Widget child;

        switch (snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.waiting:
          case ConnectionState.active:
            child = Container();
            break;
          case ConnectionState.done:
            if (snapshot.hasData) {
              child = AdWidget(ad: _nativeAd);
            } else {
              child = Text('Error loading ad');
            }
        }

        return Container(
          height: 330,
          child: child,
          color: const Color(0xFFFFFFFF),
        );
      },
    );
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多