Skip to content

Commit b608338

Browse files
committed
refactor(ads): convert AdmobNativeAdWidget to StatefulWidget
- Change AdmobNativeAdWidget from StatelessWidget to StatefulWidget - Add state management to handle native ad lifecycle - Implement init and dispose methods for proper resource management - Update documentation to reflect new functionality
1 parent 9ec434e commit b608338

File tree

1 file changed

+39
-18
lines changed

1 file changed

+39
-18
lines changed

lib/ads/widgets/admob_native_ad_widget.dart

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,42 +11,63 @@ import 'package:logging/logging.dart';
1111
/// and rendering it using the `AdWidget` from the `google_mobile_ads` package.
1212
/// It expects the `adObject` within the [app_ad_models.NativeAd] to be a fully
1313
/// loaded [admob.NativeAd] instance.
14+
///
15+
/// This is a [StatefulWidget] to properly manage the lifecycle of the native
16+
/// ad object, ensuring it is disposed when the widget is removed from the tree.
1417
/// {@endtemplate}
15-
class AdmobNativeAdWidget extends StatelessWidget {
18+
class AdmobNativeAdWidget extends StatefulWidget {
1619
/// {@macro admob_native_ad_widget}
1720
const AdmobNativeAdWidget({required this.nativeAd, super.key});
1821

1922
/// The generic native ad model which contains the provider-specific ad object.
2023
final app_ad_models.NativeAd nativeAd;
2124

2225
@override
23-
Widget build(BuildContext context) {
24-
final adObject = nativeAd.adObject;
26+
State<AdmobNativeAdWidget> createState() => _AdmobNativeAdWidgetState();
27+
}
28+
29+
class _AdmobNativeAdWidgetState extends State<AdmobNativeAdWidget> {
30+
admob.NativeAd? _ad;
31+
final Logger _logger = Logger('AdmobNativeAdWidget');
2532

26-
// Safely cast the generic ad object to the expected AdMob native ad type.
27-
if (adObject is! admob.NativeAd) {
28-
Logger('AdmobNativeAdWidget').severe(
33+
@override
34+
void initState() {
35+
super.initState();
36+
// Ensure the adObject is of the correct type and assign it.
37+
if (widget.nativeAd.adObject is admob.NativeAd) {
38+
_ad = widget.nativeAd.adObject as admob.NativeAd;
39+
} else {
40+
_logger.severe(
2941
'The provided ad object is not of type admob.NativeAd. '
30-
'Received: ${adObject.runtimeType}. Ad will not be displayed.',
42+
'Received: ${widget.nativeAd.adObject.runtimeType}. Ad will not be displayed.',
3143
);
32-
// Return an empty widget if the ad object is not of the correct type
33-
// to prevent runtime errors.
44+
}
45+
}
46+
47+
@override
48+
void dispose() {
49+
// Dispose the native ad when the widget is removed from the tree.
50+
// This is crucial for releasing native resources and preventing crashes.
51+
_ad?.dispose();
52+
_logger.info('AdmobNativeAdWidget disposed and native ad released.');
53+
super.dispose();
54+
}
55+
56+
@override
57+
Widget build(BuildContext context) {
58+
if (_ad == null) {
3459
return const SizedBox.shrink();
3560
}
3661

37-
// The AdWidget from the google_mobile_ads package handles the rendering
38-
// of the pre-loaded native ad.
39-
// We wrap it in a SizedBox to provide explicit height constraints,
40-
// which is crucial for platform views (like native ads) within scrollable
41-
// lists to prevent "unbounded height" errors.
42-
final adHeight = switch (nativeAd.templateType) {
43-
app_ad_models.NativeAdTemplateType.small => 120, // Example height for small template
44-
app_ad_models.NativeAdTemplateType.medium => 340, // Example height for medium template
62+
// Determine the height based on the native ad template type.
63+
final adHeight = switch (widget.nativeAd.templateType) {
64+
app_ad_models.NativeAdTemplateType.small => 120,
65+
app_ad_models.NativeAdTemplateType.medium => 340,
4566
};
4667

4768
return SizedBox(
4869
height: adHeight.toDouble(),
49-
child: admob.AdWidget(ad: adObject),
70+
child: admob.AdWidget(ad: _ad!),
5071
);
5172
}
5273
}

0 commit comments

Comments
 (0)