问题描述
我有 Flutter 项目,我在屏幕上添加了一个横幅广告,但我需要在同一屏幕上加载更多, 我尝试在不同的地方重复调用该函数
======== 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.
我可以在同一个屏幕上加载多个横幅吗?
这是 Github 上的链接 https://github.com/Hussamedeen/MyDealApp
HomeScreen.dart
解决方法
由于您没有提供任何代码,我会根据我认为您可以做到的方式进行假设和回答。
如果您在预定义的固定位置展示广告,则需要为每个位置创建一个新的 BannerAd
。您还必须像这样单独加载这些 BannerAd
:
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,);
myBannerNth.load();
final adWidgetNth = AdWidget(ad: myBannerNth);
其中 myBannerNth/adWidgetNth 是第 n 个横幅/广告小部件。
对于动态的、自动生成的情况,例如在 ListView.separated
中,您可以这样做:
// 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>',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,)
其中 ads
是一个 Map
,其值是各个动态自动生成的横幅广告。
来源:
https://github.com/googleads/googleads-mobile-flutter/issues/36
还有其他方法可以做到,例如在包的示例文件夹中创建另一个有状态的类。
静态未来 getBannerWidget( {@required BuildContext 上下文, 广告尺寸广告尺寸, }) 异步{
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,);
}
在屏幕上:
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,);
}
},