Overview
Interstitial ads are full-screen ads that cover the entire screen. They are effective when displayed at natural transition points (e.g., after completing a game level, page transitions, etc.).
Key Features
- Full-screen ads that cover the entire display
- Supports image and video ads
- Provides fullscreen event callbacks
- Flexible timing control with separate loading and showing
Use the test unit ID in development: PUBLIC_TEST_UNIT_ID_INTERSTITIAL
AdropInterstitialAd
Constructor
AdropInterstitialAd({
required String unitId,
AdropInterstitialListener? listener,
})
Parameters
| Parameter | Type | Required | Description |
|---|
unitId | String | Y | Unit ID created in Ad Control console |
listener | AdropInterstitialListener | N | Ad event listener |
Properties
| Property | Type | Description |
|---|
isLoaded | bool | Whether the ad has finished loading |
unitId | String | Ad unit ID |
creativeId | String | Creative ID |
txId | String | Transaction ID |
campaignId | String | Campaign ID |
destinationURL | String | Destination URL |
Methods
| Method | Return Type | Description |
|---|
load() | Future<void> | Loads the ad |
show() | Future<void> | Displays the ad on screen |
close() | Future<void> | Programmatically closes the interstitial ad (Android only, no-op on iOS) |
dispose() | Future<void> | Releases resources |
When close() is called, the ad is dismissed and the onAdDidDismissFullScreen callback is triggered. If close() is not called in the onAdBackButtonPressed callback, the ad remains displayed and only the callback is received. Whether to close the ad is up to the developer.
Basic Usage
import 'package:flutter/material.dart';
import 'package:adrop_ads_flutter/adrop_ads_flutter.dart';
class InterstitialExample extends StatefulWidget {
const InterstitialExample({super.key});
@override
State<InterstitialExample> createState() => _InterstitialExampleState();
}
class _InterstitialExampleState extends State<InterstitialExample> {
bool isLoaded = false;
AdropInterstitialAd? interstitialAd;
@override
void initState() {
super.initState();
_createInterstitialAd();
}
void _createInterstitialAd() {
interstitialAd = AdropInterstitialAd(
unitId: 'YOUR_UNIT_ID',
listener: AdropInterstitialListener(
onAdReceived: (ad) {
debugPrint('Interstitial ad loaded successfully: ${ad.creativeId}');
setState(() {
isLoaded = true;
});
},
onAdFailedToReceive: (ad, errorCode) {
debugPrint('Interstitial ad failed to load: $errorCode');
},
onAdClicked: (ad) {
debugPrint('Interstitial ad clicked');
},
onAdDidPresentFullScreen: (ad) {
debugPrint('Interstitial ad presented');
},
onAdDidDismissFullScreen: (ad) {
debugPrint('Interstitial ad dismissed');
},
onAdFailedToShowFullScreen: (ad, errorCode) {
debugPrint('Interstitial ad failed to show: $errorCode');
},
onAdBackButtonPressed: (ad) {
debugPrint('Back button pressed');
},
),
);
}
void loadAd() {
interstitialAd?.load();
}
void showAd() {
if (isLoaded) {
interstitialAd?.show();
}
}
@override
void dispose() {
interstitialAd?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Interstitial Ad Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: loadAd,
child: const Text('Load Ad'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: isLoaded ? showAd : null,
child: const Text('Show Ad'),
),
],
),
),
);
}
}
AdropInterstitialListener
Listener to handle interstitial ad events.
Callbacks
AdropInterstitialListener(
onAdReceived: (AdropAd ad) {
// Ad loaded successfully
},
onAdClicked: (AdropAd ad) {
// Ad clicked
},
onAdImpression: (AdropAd ad) {
// Ad impression
},
onAdWillPresentFullScreen: (AdropAd ad) {
// About to present ad (iOS only)
},
onAdDidPresentFullScreen: (AdropAd ad) {
// Ad presented
},
onAdWillDismissFullScreen: (AdropAd ad) {
// About to dismiss ad (iOS only)
},
onAdDidDismissFullScreen: (AdropAd ad) {
// Ad dismissed
},
onAdFailedToReceive: (AdropAd ad, AdropErrorCode errorCode) {
// Ad failed to load
},
onAdFailedToShowFullScreen: (AdropAd ad, AdropErrorCode errorCode) {
// Ad failed to show
},
onAdBackButtonPressed: (AdropAd ad) {
// Back button pressed (Android only)
},
)
Callback Descriptions
| Callback | Description |
|---|
onAdReceived | Called when ad is loaded successfully |
onAdClicked | Called when ad is clicked |
onAdImpression | Called when ad impression occurs |
onAdWillPresentFullScreen | Called before ad is presented (iOS only) |
onAdDidPresentFullScreen | Called after ad is presented |
onAdWillDismissFullScreen | Called before ad is dismissed (iOS only) |
onAdDidDismissFullScreen | Called after ad is dismissed |
onAdFailedToReceive | Called when ad fails to load |
onAdFailedToShowFullScreen | Called when ad fails to show |
onAdBackButtonPressed | Called when the user presses the back button while the ad is displayed (Android only) |
Ad Lifecycle
Recreating Ads
Interstitial ads are single-use. Once shown, they cannot be displayed again, so you must recreate the instance to load a new ad.
class _InterstitialState extends State<InterstitialWidget> {
bool isLoaded = false;
bool isShown = false;
AdropInterstitialAd? interstitialAd;
@override
void initState() {
super.initState();
_createInterstitialAd();
}
void _createInterstitialAd() {
interstitialAd?.dispose();
interstitialAd = AdropInterstitialAd(
unitId: 'YOUR_UNIT_ID',
listener: AdropInterstitialListener(
onAdReceived: (ad) {
setState(() {
isLoaded = true;
});
},
onAdDidPresentFullScreen: (ad) {
setState(() {
isShown = true;
});
},
onAdDidDismissFullScreen: (ad) {
// Prepare new ad after dismissal
_createInterstitialAd();
interstitialAd?.load();
},
),
);
setState(() {
isLoaded = false;
isShown = false;
});
}
@override
void dispose() {
interstitialAd?.dispose();
super.dispose();
}
}
Error Handling
class _InterstitialState extends State<InterstitialWidget> {
bool isLoaded = false;
AdropErrorCode? errorCode;
AdropInterstitialAd? interstitialAd;
void _createInterstitialAd() {
interstitialAd = AdropInterstitialAd(
unitId: 'YOUR_UNIT_ID',
listener: AdropInterstitialListener(
onAdReceived: (ad) {
setState(() {
isLoaded = true;
errorCode = null;
});
},
onAdFailedToReceive: (ad, error) {
setState(() {
isLoaded = false;
errorCode = error;
});
_handleError(error);
},
onAdFailedToShowFullScreen: (ad, error) {
setState(() {
errorCode = error;
});
_handleError(error);
},
),
);
}
void _handleError(AdropErrorCode error) {
switch (error) {
case AdropErrorCode.network:
debugPrint('Network error occurred.');
break;
case AdropErrorCode.adNoFill:
debugPrint('No ad available to show.');
break;
case AdropErrorCode.adShown:
debugPrint('Ad has already been shown.');
break;
default:
debugPrint('Error occurred: ${error.code}');
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: interstitialAd?.load,
child: const Text('Load Ad'),
),
ElevatedButton(
onPressed: isLoaded ? interstitialAd?.show : null,
child: const Text('Show Ad'),
),
if (errorCode != null)
Text(
'Error: ${errorCode?.code}',
style: const TextStyle(color: Colors.red),
),
],
);
}
}
Best Practices
1. Show at Appropriate Times
Display interstitial ads at natural transition points.
// Good: After level completion
void onLevelComplete() {
showInterstitialAd();
navigateToNextLevel();
}
// Bad: Right after app start
void onAppStart() {
showInterstitialAd(); // Degrades user experience
}
2. Preload Ads
Preloading ads allows you to show them without delay when needed.
class GameScreen extends StatefulWidget {
@override
State<GameScreen> createState() => _GameScreenState();
}
class _GameScreenState extends State<GameScreen> {
AdropInterstitialAd? interstitialAd;
bool isAdReady = false;
@override
void initState() {
super.initState();
_preloadAd();
}
void _preloadAd() {
interstitialAd = AdropInterstitialAd(
unitId: 'YOUR_UNIT_ID',
listener: AdropInterstitialListener(
onAdReceived: (ad) {
setState(() {
isAdReady = true;
});
},
onAdDidDismissFullScreen: (ad) {
// Preload next ad
_preloadAd();
},
),
);
interstitialAd?.load();
}
void showAdIfReady() {
if (isAdReady) {
interstitialAd?.show();
setState(() {
isAdReady = false;
});
}
}
@override
void dispose() {
interstitialAd?.dispose();
super.dispose();
}
}
3. Frequency Capping
Limit ad frequency for better user experience.
class AdManager {
static int _interstitialCount = 0;
static const int _maxInterstitialsPerSession = 3;
static DateTime? _lastInterstitialTime;
static const Duration _minInterval = Duration(minutes: 2);
static bool canShowInterstitial() {
if (_interstitialCount >= _maxInterstitialsPerSession) {
return false;
}
if (_lastInterstitialTime != null) {
final elapsed = DateTime.now().difference(_lastInterstitialTime!);
if (elapsed < _minInterval) {
return false;
}
}
return true;
}
static void onInterstitialShown() {
_interstitialCount++;
_lastInterstitialTime = DateTime.now();
}
}
4. Resource Management
Always release unused ad instances.
@override
void dispose() {
interstitialAd?.dispose();
super.dispose();
}
Complete Example
import 'package:flutter/material.dart';
import 'package:adrop_ads_flutter/adrop_ads_flutter.dart';
class InterstitialAdPage extends StatefulWidget {
const InterstitialAdPage({super.key});
@override
State<InterstitialAdPage> createState() => _InterstitialAdPageState();
}
class _InterstitialAdPageState extends State<InterstitialAdPage> {
bool isLoaded = false;
bool isLoading = false;
bool isShown = false;
AdropErrorCode? errorCode;
AdropInterstitialAd? interstitialAd;
@override
void initState() {
super.initState();
_createInterstitialAd();
}
void _createInterstitialAd() {
interstitialAd?.dispose();
interstitialAd = AdropInterstitialAd(
unitId: 'PUBLIC_TEST_UNIT_ID_INTERSTITIAL', // Test unit ID
listener: AdropInterstitialListener(
onAdReceived: (ad) {
debugPrint('Ad loaded successfully');
debugPrint('Creative ID: ${ad.creativeId}');
debugPrint('Campaign ID: ${ad.campaignId}');
setState(() {
isLoaded = true;
isLoading = false;
errorCode = null;
});
},
onAdClicked: (ad) {
debugPrint('Ad clicked: ${ad.destinationURL}');
},
onAdImpression: (ad) {
debugPrint('Ad impression: ${ad.creativeId}');
},
onAdWillPresentFullScreen: (ad) {
debugPrint('Ad will present');
},
onAdDidPresentFullScreen: (ad) {
debugPrint('Ad presented');
setState(() {
isShown = true;
});
},
onAdWillDismissFullScreen: (ad) {
debugPrint('Ad will dismiss');
},
onAdDidDismissFullScreen: (ad) {
debugPrint('Ad dismissed');
// Prepare new ad
_createInterstitialAd();
},
onAdFailedToReceive: (ad, error) {
debugPrint('Ad failed to load: $error');
setState(() {
isLoaded = false;
isLoading = false;
errorCode = error;
});
},
onAdFailedToShowFullScreen: (ad, error) {
debugPrint('Ad failed to show: $error');
setState(() {
errorCode = error;
});
},
onAdBackButtonPressed: (ad) {
debugPrint('Back button pressed');
},
),
);
setState(() {
isLoaded = false;
isShown = false;
errorCode = null;
});
}
void loadAd() {
setState(() {
isLoading = true;
errorCode = null;
});
interstitialAd?.load();
}
void showAd() {
if (isLoaded) {
interstitialAd?.show();
}
}
@override
void dispose() {
interstitialAd?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Interstitial Ad Example'),
),
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Load button
ElevatedButton(
onPressed: isLoading ? null : loadAd,
child: Text(isLoading ? 'Loading...' : 'Load Ad'),
),
const SizedBox(height: 16),
// Show button
ElevatedButton(
onPressed: isLoaded ? showAd : null,
child: const Text('Show Ad'),
),
const SizedBox(height: 16),
// Reset button
TextButton(
onPressed: (isShown || errorCode != null)
? () => _createInterstitialAd()
: null,
child: const Text('Reset'),
),
const SizedBox(height: 24),
// Status display
Text('Loaded: ${isLoaded ? "Yes" : "No"}'),
Text('Shown: ${isShown ? "Yes" : "No"}'),
// Error display
if (errorCode != null) ...[
const SizedBox(height: 16),
Text(
'Error: ${errorCode?.code}',
style: const TextStyle(color: Colors.red),
),
],
],
),
),
),
);
}
}
Backfill Ads
When backfill ads are enabled, backfill ads are automatically loaded when direct ads are unavailable. Use the isBackfilled property to check if the ad is a backfill ad.
interstitialAd = AdropInterstitialAd(
unitId: 'YOUR_UNIT_ID',
listener: AdropInterstitialListener(
onAdReceived: (ad) {
if (ad.isBackfilled) {
debugPrint('Backfill ad loaded');
} else {
debugPrint('Direct ad loaded');
}
},
onAdFailedToReceive: (ad, errorCode) {
switch (errorCode) {
case AdropErrorCode.adNoFill:
debugPrint('No direct ad, requesting backfill...');
break;
case AdropErrorCode.backfillNoFill:
debugPrint('No backfill ad available');
break;
default:
debugPrint('Ad load failed: ${errorCode.code}');
}
},
),
);
To use backfill ads, add the backfill dependency to native platforms. See Getting Started.
Next Steps