2

我正在尝试在 a 中动态调用广告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;

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

4

1 回答 1

0

我真的不确定你是如何实现这个小部件的,因为你只展示了你类的一部分,但我相信如果你为原生广告制作了独立的小部件并像这样进行初始化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),
        );
      },
    );
  }
}
于 2021-05-03T04:41:02.553 回答