On this page13 sections
Lecture 007 — Native Ads
| Category | 3 — Native & Rewarded Ads |
| Lecture | 007 of 010 |
| Estimated video length | 18 min |
| Target | Flutter 3.44 · Dart 3.12 · google_mobile_ads 9 |
| Level | Beginner |
| Source code | GitHub — urraan_admob_final |
A native ad takes the shape of your own screen. With a template style you set colours and fonts from Dart and Google fills in the rest — no platform code.
Contents
Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways
Prerequisites
Lectures 001–004.
Connection With Previous Lectures
Banner ads are a plain strip. Native ads fit into content, which usually earns more clicks and annoys less.
Learning Objectives
By the end of this lecture you will be able to:
- Create a
NativeAdwith aNativeTemplateStyle - Choose small or medium templates
- Show it with
AdWidgetin a fixed-height box - Dispose it with the screen
Lesson
1. The Helper
// lib/admob/native_ad_helper.dart
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'admob_manager.dart';
class NativeAdHelper {
NativeAd? _nativeAd;
bool isLoaded = false;
void loadNativeAd(
VoidCallback onAdLoaded, {
TemplateType type = TemplateType.small,
}) {
_nativeAd?.dispose();
isLoaded = false;
_nativeAd = NativeAd(
adUnitId: AdmobManager.nativeId,
listener: NativeAdListener(
onAdLoaded: (_) {
isLoaded = true;
onAdLoaded();
},
onAdFailedToLoad: (ad, error) {
debugPrint('Native failed: ${error.code} ${error.message}');
ad.dispose();
},
),
request: const AdRequest(),
nativeTemplateStyle: NativeTemplateStyle(
templateType: type,
mainBackgroundColor: const Color(0xfffffbed),
callToActionTextStyle: NativeTemplateTextStyle(
textColor: Colors.white,
style: NativeTemplateFontStyle.monospace,
size: 16,
),
primaryTextStyle: NativeTemplateTextStyle(
textColor: Colors.black,
style: NativeTemplateFontStyle.bold,
size: 16,
),
secondaryTextStyle: NativeTemplateTextStyle(
textColor: Colors.black,
style: NativeTemplateFontStyle.italic,
size: 16,
),
tertiaryTextStyle: NativeTemplateTextStyle(
textColor: Colors.black,
style: NativeTemplateFontStyle.normal,
size: 16,
),
),
)..load();
}
NativeAd? get nativeAd => isLoaded ? _nativeAd : null;
void dispose() => _nativeAd?.dispose();
static Widget getNativeAdView({
required bool isPurchase,
required bool isLoaded,
required NativeAd? nativeAd,
double height = 100,
}) {
if (isPurchase || !isLoaded || nativeAd == null) return const SizedBox();
return Padding(
padding: const EdgeInsets.all(5),
child: SizedBox(
height: height,
width: double.infinity,
child: AdWidget(ad: nativeAd),
),
);
}
}TemplateType.smallor.mediumselects Google's built-in layout.NativeTemplateStylesets the background, button text and text styles.- The widget returns an empty
SizedBoxuntil the ad has loaded, so nothing broken shows.
2. The Screen
// lib/screen_native_ads.dart
import 'package:flutter/material.dart';
import 'admob/native_ad_helper.dart';
class ScreenNativeAds extends StatefulWidget {
const ScreenNativeAds({super.key});
@override
State<ScreenNativeAds> createState() => _ScreenNativeAdsState();
}
class _ScreenNativeAdsState extends State<ScreenNativeAds> {
final nativeAdHelper = NativeAdHelper();
@override
void initState() {
super.initState();
nativeAdHelper.loadNativeAd(() {
if (mounted) setState(() {});
});
}
@override
void dispose() {
nativeAdHelper.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Native Ad Example')),
body: Column(
children: [
const Expanded(child: Center(child: Text('Main content goes here'))),
NativeAdHelper.getNativeAdView(
isPurchase: false,
isLoaded: nativeAdHelper.isLoaded,
nativeAd: nativeAdHelper.nativeAd,
height: 120,
),
],
),
);
}
}- The ad sits under the content with
height: 120. - A native ad must have a bounded height; an unbounded
AdWidgetin aColumnthrows a layout error. - A medium template needs more height (about 350).
Code Examples
Example 1 — Medium Template
nativeAdHelper.loadNativeAd(() {
if (mounted) setState(() {});
}, type: TemplateType.medium);and give the view height: 350.
Common Beginner Mistakes
1. No height — the ad throws a layout error.
2. Not disposing — memory leak.
3. Hiding the "Ad" label or disguising the ad as content — against policy; the template keeps the label.
Best Practices
- Match colours to your theme
- Give the ad a fixed height
- Place it between content, not over buttons
Mini Challenge
Show the ad with TemplateType.medium and a taller box, and compare earnings potential in the dashboard later.
Practice Questions
- What does the template style control?
- Why is a fixed height needed?
- What is shown before the ad loads?
- What must you do in
dispose?
Practice Answers
- Colours, fonts and layout type.
- The ad view needs bounded size inside a
Column. - Nothing (
SizedBox). - Dispose the ad.
Key Takeaways
- Native ads follow your design
- Fixed height; dispose them
- Never hide the ad label