Flutter :- This AdWidget is already in the Widget tree. How to disable this exception. Using Provider
This is my Ad provider
import 'package:bg_remover/services/ads_helper.dart'; import 'package:flutter/material.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; class AdaptiveBannerAdProvider with ChangeNotifier{ BannerAd? _anchoredAdaptiveAd; bool _isLoaded = false; BannerAd? get anchoredAdaptiveAd => _anchoredAdaptiveAd; bool get isAdLoaded => _isLoaded; Future<void> loadAnchoredAdaptiveAd(BuildContext context) async { final AnchoredAdaptiveBannerAdSize? size = await AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize( MediaQuery.of(context).size.width.truncate()); if (size == null) { debugPrint('Unable to get height of anchored banner.'); return; } _anchoredAdaptiveAd = BannerAd( adUnitId: AdHelper.bannerAdUnitId, size: size, request: const AdRequest(), listener: BannerAdListener( onAdLoaded: (Ad ad) { debugPrint('$ad has been >>>>>loaded: ${ad.responseInfo}'); //there was an error of @This AdWidget is already in the Widget tree@ // so for that we apply this widgetsBinding to notify listener //and place the banner add in FutureBuilder and that's work // WidgetsBinding.instance.addPostFrameCallback((_) { // _isLoaded = true; // notifyListeners(); // }); // Ad was not showing when loaded _isLoaded = true; notifyListeners(); }, onAdFailedToLoad: (Ad ad, LoadAdError error) { debugPrint('Anchored adaptive banner failedToLoad: $error'); ad.dispose(); }, ), ); return _anchoredAdaptiveAd!.load(); } void disposeAd() { _anchoredAdaptiveAd?.dispose(); } }
call it here to display Ad:
import 'package:bg_remover/utils/routes/routes_name.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:gap/gap.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'package:provider/provider.dart'; import '../provider/ads_provider/adaptiveBanner_ad_provider.dart'; import '../utils/colors.dart'; import '../utils/images_assets_path.dart'; import '../utils/strings.dart'; import 'bottom_tabs/home_page.dart'; import 'bottom_tabs/project_page.dart'; import 'bottom_tabs/settings_page.dart'; class HomeFeedPage extends StatefulWidget{ const HomeFeedPage({Key? key}) : super(key: key); @override State<HomeFeedPage> createState() => _HomeFeedPageState(); } class _HomeFeedPageState extends State<HomeFeedPage>{ int index = 1; final List<Widget> pages = const [ ProjectPage(), HomePage(), SettingsPage(), ]; final List<String> icons = [ AssetImages.projectIcon, AssetImages.inactiveHomeIcon, AssetImages.settingsIcon, ]; final List<String> titles = const [ Strings.projects, Strings.home, Strings.settings, ]; void _onIconPressed(int newIndex) { if (newIndex == 2) { Navigator.pushNamed(context, RoutesName.settings); } else { setState(() { index = newIndex; }); } } @override void didChangeDependencies() { super.didChangeDependencies(); final adaptiveAdProvider = Provider.of<AdaptiveBannerAdProvider>(context, listen: false); adaptiveAdProvider.loadAnchoredAdaptiveAd(context); } @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, body: Column( children: [ Expanded(child: pages[index]), displayAd(), _buildBottomBar(), ], ), ); } Widget _buildBottomBar() { return Container( padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 4), color: AppColors.bottomBarColor, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: List.generate( icons.length, (int i) => GestureDetector( onTap: () => _onIconPressed(i), child: _buildIconColumn(i), ), ), ), ); } Widget _buildIconColumn(int i) { final bool isActiveHome = index == 1 && i == 1; final String iconPath = isActiveHome ? AssetImages.homeIcon : icons[i]; return Column( children: [ AnimatedContainer( duration: const Duration(milliseconds: 300), width: 70, height: 35, decoration: BoxDecoration( color: index == i ? AppColors.activeTabColor : Colors.transparent, borderRadius: BorderRadius.circular(20), ), child: Padding( padding: const EdgeInsets.all(8.0), child: SvgPicture.asset( iconPath, colorFilter: ColorFilter.mode( index == i ? AppColors.whiteColor : AppColors.activeColor, BlendMode.srcIn, ), ), ), ), const Gap(5), Text( titles[i], style: TextStyle( color: index == i ? AppColors.whiteColor : AppColors.activeColor, fontWeight: index == i ? FontWeight.w700 : null, ), ), ], ); } Widget displayAd() { return Consumer<AdaptiveBannerAdProvider>( builder: (context, adProvider, _) { if (adProvider.isAdLoaded) { return SizedBox( width: adProvider.anchoredAdaptiveAd!.size.width.toDouble(), height: adProvider.anchoredAdaptiveAd!.size.height.toDouble(), child: AdWidget(ad: adProvider.anchoredAdaptiveAd!), ); } else { return Container( color: AppColors.yellowColor, width: adProvider.anchoredAdaptiveAd?.size.width.toDouble(), height: adProvider.anchoredAdaptiveAd?.size.height.toDouble(), child: Center( child: Text( 'Ad is Loading.......', style: TextStyle(color: AppColors.whiteColor), ), ), ); } }, ); } verride void dispose() { Provider.of<AdaptiveBannerAdProvider>(context, listen: false).disposeAd(); super.dispose(); } } @
working fine when I go to next having same process to display ad show error : Flutter :- This AdWidget is already in the Widget tree. How to disable this exception. And what does it mean?
Above Code is Working fine on HomeFeed Page. when I go to next having same process to display ad error : Flutter :- This AdWidget is already in the Widget tree. How to disable this exception. And what does it mean?