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?