Flutter 2空安全环境下集成Google Mobile Ads SDK遇类型匹配错误求助
Hey there! I see exactly what's going on here—this is a classic null safety hiccup after your Flutter 2 migration, paired with the Google Mobile Ads SDK's strict type requirements. Let's break it down and fix it up:
Why the Error Happens
Your _bannerAd variable is declared as BannerAd? (a nullable type), but the AdWidget constructor expects a non-null AdWithView parameter. Even though BannerAd does implement AdWithView, Dart's null safety rules won't let you pass a nullable value directly to a non-null parameter—this is a good thing, it prevents potential runtime crashes if the ad hasn't finished loading yet.
The Fix
You've got two solid ways to resolve this, depending on how you want to handle the ad loading state:
1. Show the Ad Only When It's Loaded (Recommended)
Wrap your ad container in a null check to ensure _bannerAd isn't null before rendering AdWidget. This also lets you show a friendly loading state while the ad is being fetched:
@override Widget build(BuildContext context) { final userProvider = Provider.of<UserProvider>(context); return Scaffold( // ... your existing appBar and scaffold setup ... body: Column( children:[ Expanded( // Added this to fix layout overflow issues with ListView in Column child: ListView.builder( itemCount: userProvider.orders.length, itemBuilder: (_, index) { OrderModel _order = userProvider.orders[index]; return ListTile( leading: Text( "\$${_order.total}", style: const TextStyle(fontSize: 15, color: Colors.black), ), title: Text(_order.description), subtitle: Text( DateTime.fromMillisecondsSinceEpoch(_order.createdAt) .toString()), trailing: Text(_order.status, style: const TextStyle(fontSize: 18, color: Colors.black)), ); }, ), ), // Modified ad section here if (_bannerAd != null) Container( alignment: Alignment.center, child: AdWidget(ad: _bannerAd!), // Use ! to assert non-null now that we've checked width: _bannerAd!.size.width.toDouble(), height: _bannerAd!.size.height.toDouble(), ) else // Show a placeholder while ad loads Container( height: 50, color: Colors.grey[200], child: const Center(child: Text('Loading ad...')), ) ] ), ); }
Quick note: I wrapped your ListView.builder in an Expanded widget—this fixes a common layout overflow issue when using ListView inside a Column, since ListView has unbounded height by default.
2. Use late for Non-Nullable Declaration (Careful!)
If you're absolutely certain _bannerAd will be initialized before build runs (which it is in your initState), you can declare it as late BannerAd _bannerAd instead of BannerAd?:
class _OrdersScreenState extends State<OrdersScreen> { late BannerAd _bannerAd; // No longer nullable @override void initState() { super.initState(); _bannerAd = BannerAd( // ... your existing ad configuration ... ); _bannerAd.load(); } @override void dispose() { _bannerAd.dispose(); super.dispose(); } // Then in build, you can use it directly: child: AdWidget(ad: _bannerAd), }
Warning: Only use this if you're 100% sure _bannerAd is initialized before build. If the ad fails to load, this won't cause a crash, but you might still want to add a check to hide the container if the ad didn't load successfully.
Why the Official Docs Don't Mention This
The Google Mobile Ads docs haven't been fully updated for Flutter's null safety yet, so their examples skip over these nullable type checks. Now that you're on Flutter 2, you have to account for null safety in all your code—this is just part of the process!
内容的提问来源于stack exchange,提问作者Akash Rajoria

