> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adrop.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Interstitial Ads

> Learn how to implement interstitial ads in your Flutter app.

## 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

<Note>
  Use the test unit ID in development: `PUBLIC_TEST_UNIT_ID_INTERSTITIAL`
</Note>

***

## AdropInterstitialAd

### Constructor

```dart theme={null}
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                       |
| `browserTarget`  | `BrowserTarget?` | Browser target (external or internal) |

### 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                                                       |

<Note>
  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.
</Note>

***

## Basic Usage

```dart theme={null}
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

```dart theme={null}
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

```mermaid theme={null}
graph TD
    A[Create] --> B[Call load]
    B --> C{Load Result}
    C -->|Success| D[onAdReceived]
    C -->|Failure| E[onAdFailedToReceive]
    D --> F[Call show]
    F --> G{Show Result}
    G -->|Success| H[onAdWillPresentFullScreen]
    G -->|Failure| I[onAdFailedToShowFullScreen]
    H --> J[onAdDidPresentFullScreen]
    J --> K[User Interaction]
    K -->|Click| L[onAdClicked]
    K -->|Dismiss| M[onAdWillDismissFullScreen]
    K -->|Back Button Android| P[onAdBackButtonPressed]
    P -->|call close| M
    M --> N[onAdDidDismissFullScreen]
    N --> O[dispose or recreate]
```

***

## Ad Recreation

Interstitial ads are single-use. Once shown, they cannot be displayed again, so you must recreate the instance to load a new ad.

```dart theme={null}
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

```dart theme={null}
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.

```dart theme={null}
// 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.

```dart theme={null}
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.

```dart theme={null}
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.

```dart theme={null}
@override
void dispose() {
  interstitialAd?.dispose();
  super.dispose();
}
```

***

## Complete Example

```dart theme={null}
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. You can handle backfill-related errors using the error code.

```dart theme={null}
interstitialAd = AdropInterstitialAd(
  unitId: 'YOUR_UNIT_ID',
  listener: AdropInterstitialListener(
    onAdReceived: (ad) {
      debugPrint('Ad loaded: ${ad.creativeId}');
    },
    onAdFailedToReceive: (ad, errorCode) {
      switch (errorCode) {
        case AdropErrorCode.adNoFill:
          debugPrint('No direct ad available');
          break;
        case AdropErrorCode.backfillNoFill:
          debugPrint('No backfill ad available either');
          break;
        default:
          debugPrint('Ad load failed: ${errorCode.code}');
      }
    },
  ),
);
```

<Note>
  To use backfill ads, add the backfill dependency to native platforms. See [Getting Started](/sdk/flutter/overview).
</Note>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Rewarded Ads" href="/sdk/flutter/rewarded">
    Implement rewarded ads that provide rewards
  </Card>

  <Card title="Popup Ads" href="/sdk/flutter/popup">
    Implement popup-style ads
  </Card>

  <Card title="Reference" href="/sdk/flutter/reference">
    Reference types, methods, and error codes
  </Card>
</CardGroup>
