Skip to main content

Overview

Rewarded ads are full-screen ads where users receive rewards after watching the entire ad. Use them to provide rewards such as in-game items, additional content, etc.

Key Features

  • Full-screen ads that cover the entire screen
  • Video ad support
  • Reward event callbacks
  • Reward type and amount information
  • Separate load and show for flexible timing control
Use the test unit ID in development: PUBLIC_TEST_UNIT_ID_REWARDED

AdropRewardedAd

Constructor

AdropRewardedAd({
  required String unitId,
  AdropRewardedListener? listener,
})
Parameters
ParameterTypeRequiredDescription
unitIdStringYUnit ID created in the Ad Control console
listenerAdropRewardedListenerNAd event listener

Properties

PropertyTypeDescription
isLoadedboolWhether the ad is loaded
unitIdStringAd unit ID
creativeIdStringCreative ID
txIdStringTransaction ID
campaignIdStringCampaign ID
destinationURLStringDestination URL

Methods

MethodReturn TypeDescription
load()Future<void>Loads the ad
show()Future<void>Shows the ad on screen
dispose()Future<void>Releases resources

Basic Usage

import 'package:flutter/material.dart';
import 'package:adrop_ads_flutter/adrop_ads_flutter.dart';

class RewardedExample extends StatefulWidget {
  const RewardedExample({super.key});

  @override
  State<RewardedExample> createState() => _RewardedExampleState();
}

class _RewardedExampleState extends State<RewardedExample> {
  bool isLoaded = false;
  AdropRewardedAd? rewardedAd;

  @override
  void initState() {
    super.initState();
    _createRewardedAd();
  }

  void _createRewardedAd() {
    rewardedAd = AdropRewardedAd(
      unitId: 'YOUR_UNIT_ID',
      listener: AdropRewardedListener(
        onAdReceived: (ad) {
          debugPrint('Rewarded ad loaded: ${ad.creativeId}');
          setState(() {
            isLoaded = true;
          });
        },
        onAdFailedToReceive: (ad, errorCode) {
          debugPrint('Rewarded ad failed to load: $errorCode');
        },
        onAdClicked: (ad) {
          debugPrint('Rewarded ad clicked');
        },
        onAdDidPresentFullScreen: (ad) {
          debugPrint('Rewarded ad presented');
        },
        onAdDidDismissFullScreen: (ad) {
          debugPrint('Rewarded ad dismissed');
        },
        onAdFailedToShowFullScreen: (ad, errorCode) {
          debugPrint('Rewarded ad failed to show: $errorCode');
        },
        onAdEarnRewardHandler: (ad, type, amount) {
          debugPrint('Reward earned: type=$type, amount=$amount');
          _giveReward(type, amount);
        },
      ),
    );
  }

  void _giveReward(int type, int amount) {
    // Implement reward logic
    // e.g., coins, items, extra lives, etc.
  }

  void loadAd() {
    rewardedAd?.load();
  }

  void showAd() {
    if (isLoaded) {
      rewardedAd?.show();
    }
  }

  @override
  void dispose() {
    rewardedAd?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Rewarded 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('Watch Ad for Reward'),
            ),
          ],
        ),
      ),
    );
  }
}

AdropRewardedListener

A listener for handling rewarded ad events.

Callback Functions

AdropRewardedListener(
  onAdReceived: (AdropAd ad) {
    // Ad loaded successfully
  },
  onAdClicked: (AdropAd ad) {
    // Ad clicked
  },
  onAdImpression: (AdropAd ad) {
    // Ad impression
  },
  onAdWillPresentFullScreen: (AdropAd ad) {
    // Ad about to be presented (iOS only)
  },
  onAdDidPresentFullScreen: (AdropAd ad) {
    // Ad presented
  },
  onAdWillDismissFullScreen: (AdropAd ad) {
    // Ad about to be dismissed (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
  },
  onAdEarnRewardHandler: (AdropAd ad, int type, int amount) {
    // Reward earned
  },
)

Callback Descriptions

CallbackDescription
onAdReceivedCalled when ad loads successfully
onAdClickedCalled when ad is clicked
onAdImpressionCalled when ad is displayed
onAdWillPresentFullScreenCalled before ad is presented (iOS only)
onAdDidPresentFullScreenCalled after ad is presented
onAdWillDismissFullScreenCalled before ad is dismissed (iOS only)
onAdDidDismissFullScreenCalled after ad is dismissed
onAdFailedToReceiveCalled when ad fails to load
onAdFailedToShowFullScreenCalled when ad fails to show
onAdEarnRewardHandlerCalled when reward is earned

Reward Handling

Reward Callback

Process reward information in the onAdEarnRewardHandler callback.
onAdEarnRewardHandler: (ad, type, amount) {
  debugPrint('Reward earned: type=$type, amount=$amount');

  // Handle based on reward type
  switch (type) {
    case 1:
      // Coin reward
      _addCoins(amount);
      break;
    case 2:
      // Item reward
      _addItem(amount);
      break;
    default:
      // Default reward
      _giveDefaultReward(amount);
  }
}

Reward Timing

Rewards must be granted in the onAdEarnRewardHandler callback. This callback is not called if the ad is dismissed before being fully watched.
class RewardManager {
  bool _rewardEarned = false;

  void setupRewardedAd() {
    rewardedAd = AdropRewardedAd(
      unitId: 'YOUR_UNIT_ID',
      listener: AdropRewardedListener(
        onAdEarnRewardHandler: (ad, type, amount) {
          // Set reward flag
          _rewardEarned = true;
        },
        onAdDidDismissFullScreen: (ad) {
          // Check reward after ad is dismissed
          if (_rewardEarned) {
            _giveReward();
            _rewardEarned = false;
          }
        },
      ),
    );
  }
}

Ad Recreation

Rewarded ads are one-time use. Once shown, an ad cannot be displayed again, so you must recreate the instance to load a new ad.
class _RewardedState extends State<RewardedWidget> {
  bool isLoaded = false;
  bool isShown = false;
  AdropRewardedAd? rewardedAd;

  @override
  void initState() {
    super.initState();
    _createRewardedAd();
  }

  void _createRewardedAd() {
    rewardedAd?.dispose();
    rewardedAd = AdropRewardedAd(
      unitId: 'YOUR_UNIT_ID',
      listener: AdropRewardedListener(
        onAdReceived: (ad) {
          setState(() {
            isLoaded = true;
          });
        },
        onAdDidPresentFullScreen: (ad) {
          setState(() {
            isShown = true;
          });
        },
        onAdEarnRewardHandler: (ad, type, amount) {
          _giveReward(type, amount);
        },
        onAdDidDismissFullScreen: (ad) {
          // Prepare new ad after dismissal
          _createRewardedAd();
          rewardedAd?.load();
        },
      ),
    );

    setState(() {
      isLoaded = false;
      isShown = false;
    });
  }

  @override
  void dispose() {
    rewardedAd?.dispose();
    super.dispose();
  }
}

Error Handling

class _RewardedState extends State<RewardedWidget> {
  bool isLoaded = false;
  AdropErrorCode? errorCode;
  AdropRewardedAd? rewardedAd;

  void _createRewardedAd() {
    rewardedAd = AdropRewardedAd(
      unitId: 'YOUR_UNIT_ID',
      listener: AdropRewardedListener(
        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 ads available.');
        break;
      case AdropErrorCode.adShown:
        debugPrint('Ad already shown.');
        break;
      default:
        debugPrint('Error: ${error.code}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
          onPressed: rewardedAd?.load,
          child: const Text('Load Ad'),
        ),
        ElevatedButton(
          onPressed: isLoaded ? rewardedAd?.show : null,
          child: const Text('Watch Ad for Reward'),
        ),
        if (errorCode != null)
          Text(
            'Error: ${errorCode?.code}',
            style: const TextStyle(color: Colors.red),
          ),
      ],
    );
  }
}

Best Practices

1. Preload Ads

Preload ads so they can be shown immediately when users request rewards.
class GameScreen extends StatefulWidget {
  @override
  State<GameScreen> createState() => _GameScreenState();
}

class _GameScreenState extends State<GameScreen> {
  AdropRewardedAd? rewardedAd;
  bool isAdReady = false;

  @override
  void initState() {
    super.initState();
    _preloadAd();
  }

  void _preloadAd() {
    rewardedAd = AdropRewardedAd(
      unitId: 'YOUR_UNIT_ID',
      listener: AdropRewardedListener(
        onAdReceived: (ad) {
          setState(() {
            isAdReady = true;
          });
        },
        onAdEarnRewardHandler: (ad, type, amount) {
          _giveReward(type, amount);
        },
        onAdDidDismissFullScreen: (ad) {
          // Preload next ad
          _preloadAd();
        },
      ),
    );
    rewardedAd?.load();
  }

  void showRewardedAd() {
    if (isAdReady) {
      rewardedAd?.show();
      setState(() {
        isAdReady = false;
      });
    }
  }

  @override
  void dispose() {
    rewardedAd?.dispose();
    super.dispose();
  }
}

2. Inform Users About Rewards

Clearly communicate the rewards users can receive before watching the ad.
void showRewardDialog() {
  showDialog(
    context: context,
    builder: (context) => AlertDialog(
      title: const Text('Get Reward'),
      content: const Text('Watch an ad to receive 100 coins!'),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('Cancel'),
        ),
        ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
            showRewardedAd();
          },
          child: const Text('Watch Ad'),
        ),
      ],
    ),
  );
}

3. Show Ad Availability

Only enable the reward button when an ad is ready.
Widget buildRewardButton() {
  return ElevatedButton.icon(
    onPressed: isAdReady ? showRewardedAd : null,
    icon: const Icon(Icons.play_circle_outline),
    label: Text(isAdReady ? 'Watch Ad for Reward' : 'Loading Ad...'),
    style: ElevatedButton.styleFrom(
      backgroundColor: isAdReady ? Colors.green : Colors.grey,
    ),
  );
}

4. Reward Reliability

It’s recommended to verify rewards on the server.
onAdEarnRewardHandler: (ad, type, amount) async {
  try {
    // Request reward from server
    await _api.grantReward(
      userId: currentUserId,
      transactionId: ad.txId,
      rewardType: type,
      amount: amount,
    );

    // Update local state
    _updateLocalBalance(amount);
  } catch (e) {
    debugPrint('Failed to grant reward: $e');
    // Retry or handle error
  }
}

5. Resource Management

Always dispose unused ad instances.
@override
void dispose() {
  rewardedAd?.dispose();
  super.dispose();
}

Full Example

import 'package:flutter/material.dart';
import 'package:adrop_ads_flutter/adrop_ads_flutter.dart';

class RewardedAdPage extends StatefulWidget {
  const RewardedAdPage({super.key});

  @override
  State<RewardedAdPage> createState() => _RewardedAdPageState();
}

class _RewardedAdPageState extends State<RewardedAdPage> {
  bool isLoaded = false;
  bool isLoading = false;
  bool isShown = false;
  int coins = 0;
  AdropErrorCode? errorCode;
  AdropRewardedAd? rewardedAd;

  @override
  void initState() {
    super.initState();
    _createRewardedAd();
  }

  void _createRewardedAd() {
    rewardedAd?.dispose();
    rewardedAd = AdropRewardedAd(
      unitId: 'PUBLIC_TEST_UNIT_ID_REWARDED', // Test unit ID
      listener: AdropRewardedListener(
        onAdReceived: (ad) {
          debugPrint('Ad loaded');
          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
          _createRewardedAd();
        },
        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;
          });
        },
        onAdEarnRewardHandler: (ad, type, amount) {
          debugPrint('Reward earned: type=$type, amount=$amount');
          setState(() {
            coins += amount;
          });
          _showRewardNotification(amount);
        },
      ),
    );

    setState(() {
      isLoaded = false;
      isShown = false;
      errorCode = null;
    });
  }

  void loadAd() {
    setState(() {
      isLoading = true;
      errorCode = null;
    });
    rewardedAd?.load();
  }

  void showAd() {
    if (isLoaded) {
      rewardedAd?.show();
    }
  }

  void _showRewardNotification(int amount) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('You earned $amount coins!'),
        backgroundColor: Colors.green,
        duration: const Duration(seconds: 2),
      ),
    );
  }

  @override
  void dispose() {
    rewardedAd?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Rewarded Ad Example'),
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // Coin display
              Container(
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  color: Colors.amber.shade100,
                  borderRadius: BorderRadius.circular(8),
                ),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    const Icon(Icons.monetization_on, color: Colors.amber),
                    const SizedBox(width: 8),
                    Text(
                      '$coins Coins',
                      style: const TextStyle(
                        fontSize: 24,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 32),

              // Load button
              ElevatedButton(
                onPressed: isLoading ? null : loadAd,
                child: Text(isLoading ? 'Loading...' : 'Load Ad'),
              ),
              const SizedBox(height: 16),

              // Show button
              ElevatedButton.icon(
                onPressed: isLoaded ? showAd : null,
                icon: const Icon(Icons.play_circle_outline),
                label: const Text('Watch Ad for Reward'),
                style: ElevatedButton.styleFrom(
                  backgroundColor: isLoaded ? Colors.green : Colors.grey,
                ),
              ),
              const SizedBox(height: 16),

              // Reset button
              TextButton(
                onPressed: (isShown || errorCode != null)
                    ? () => _createRewardedAd()
                    : 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),
                ),
              ],
            ],
          ),
        ),
      ),
    );
  }
}

Next Steps