Build a Flutter To-Do List App with AdMob Integration Using Cursor AI

Want to build a real-world Flutter app and earn with ads? In this step-by-step tutorial, you’ll learn how to create a To-Do List app in Flutter that uses Google AdMob for monetization and SharedPreferences for local task storage.

This guide is perfect for students, indie developers, or anyone looking to monetize a simple Flutter app using Cursor AI.


✅ What You’ll Learn

  • Building a feature-based Flutter app

  • Using SharedPreferences to save tasks locally

  • Integrating Google AdMob (banner and interstitial ads)

  • Managing state with Bloc

  • Working with Cursor AI to speed up development


🛠️ Prerequisites

Before you start, make sure you have the following ready:

  • Flutter SDK (3.0+)

  • Cursor AI or another AI-based coding tool

  • Android emulator or physical device

  • Google AdMob account

  • Basic understanding of Flutter and Dart


🪜 Step-by-Step Guide

Step 1: Create a New Flutter Project

flutter create todo_admob_app
cd todo_admob_app

Step 2: Open the Project in Cursor AI

  • Open Cursor AI.

  • Navigate to the todo_admob_app project folder.

  • Prompt 

  • Paste your full app generation prompt (includes AdMob, SharedPreferences, Bloc, etc.).

  • Let Cursor AI generate your base code structure.


Step 3: Create a Google AdMob Account

  • Go to Google AdMob.

  • Sign in with your Google account.

  • Click Apps > Add App.

  • Select Android and enter your app name.

  • Copy the App ID (you’ll need it for your AndroidManifest.xml).


Step 4: Add Required Dependencies

Edit pubspec.yaml and add:

dependencies:
  flutter:
    sdk: flutter
  flutter_bloc: ^8.1.0
  shared_preferences: ^2.0.15
  google_mobile_ads: ^3.0.0

Then run:

flutter pub get

Step 5: Initialize AdMob

In main.dart:

import 'package:google_mobile_ads/google_mobile_ads.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();
  runApp(MyApp());
}

In android/app/src/main/AndroidManifest.xml, add:

<meta-data
  android:name="com.google.android.gms.ads.APPLICATION_ID"
  android:value="ca-app-pub-xxxxxxxx~yyyyyyyy" />

Replace with your actual AdMob App ID.


Step 6: Add AdMob Ads

Banner Ad

Add a banner ad at the bottom of the task list screen using the test Ad Unit ID:

BannerAd(
  adUnitId: 'ca-app-pub-3940256099942544/6300978111', // test ID
  size: AdSize.banner,
  ...
)

Interstitial Ad

Load and show an interstitial ad after adding or deleting a task:

InterstitialAd.load(
  adUnitId: 'ca-app-pub-3940256099942544/1033173712', // test ID
  ...
);

⚠️ Always use test ad unit IDs during development!


📢 Understanding the Three Main AdMob Ad Types and How to Implement Them Simply

When you integrate Google AdMob in your Flutter To-Do List app, you have three primary ad formats to consider:

1. Banner Ads

  • What it is: A small rectangular ad displayed persistently, usually at the top or bottom of the screen.

  • Why use it: It offers steady ad impressions without disrupting user experience.

  • Where to place: At the bottom of your task list screen.

  • Implementation steps:

    • Create a BannerAd object with a test ad unit ID.

    • Load the banner ad.

    • Display it inside a container aligned to the bottom.

2. Interstitial Ads

  • What it is: Full-screen ads that appear at natural transition points (e.g., after adding or deleting a task).

  • Why use it: Generates high revenue with less frequent but more engaging impressions.

  • When to show: After completing a user action like adding or deleting tasks.

  • Implementation steps:

    • Load an interstitial ad ahead of time.

    • Show it after the user finishes the action.

    • Handle ad dismissal and reload the next ad.

3. Rewarded Ads

  • What it is: Full-screen ads users watch voluntarily to earn rewards like unlocking app features.

  • Why use it: Encourages engagement and rewards users, increasing retention.

  • Use case: For example, users could watch a rewarded ad to unlock a new task priority color or theme.

  • Implementation steps:

    • Load a rewarded ad.

    • Show it when the user opts in.

    • Grant rewards once the ad is watched completely.

    • Reload for future use.


🛠️ Simple Implementation Guide for Each Ad Type

Initialize Mobile Ads SDK (Required for all ads)

In your main.dart:

import 'package:google_mobile_ads/google_mobile_ads.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();
  runApp(MyApp());
}

Banner Ad Implementation

BannerAd bannerAd = BannerAd(
  adUnitId: 'ca-app-pub-3940256099942544/6300978111', // Test ID
  size: AdSize.banner,
  request: AdRequest(),
  listener: BannerAdListener(
    onAdLoaded: (ad) => print('Banner ad loaded.'),
    onAdFailedToLoad: (ad, error) {
      ad.dispose();
      print('Failed to load banner ad: $error');
    },
  ),
);

bannerAd.load();

// In the widget tree (e.g., Scaffold's bottom area)
Container(
  width: bannerAd.size.width.toDouble(),
  height: bannerAd.size.height.toDouble(),
  child: AdWidget(ad: bannerAd),
)

Interstitial Ad Implementation

InterstitialAd? interstitialAd;

void loadInterstitialAd() {
  InterstitialAd.load(
    adUnitId: 'ca-app-pub-3940256099942544/1033173712', // Test ID
    request: AdRequest(),
    adLoadCallback: InterstitialAdLoadCallback(
      onAdLoaded: (ad) {
        interstitialAd = ad;
        print('Interstitial ad loaded.');
      },
      onAdFailedToLoad: (error) {
        print('Failed to load interstitial ad: $error');
      },
    ),
  );
}

void showInterstitialAd() {
  if (interstitialAd == null) {
    print('Interstitial ad not ready.');
    return;
  }
  interstitialAd!.fullScreenContentCallback = FullScreenContentCallback(
    onAdDismissedFullScreenContent: (ad) {
      ad.dispose();
      loadInterstitialAd();
    },
    onAdFailedToShowFullScreenContent: (ad, error) {
      ad.dispose();
      print('Failed to show interstitial ad: $error');
      loadInterstitialAd();
    },
  );
  interstitialAd!.show();
  interstitialAd = null;
}

Rewarded Ad Implementation

RewardedAd? rewardedAd;

void loadRewardedAd() {
  RewardedAd.load(
    adUnitId: 'ca-app-pub-3940256099942544/5224354917', // Test ID
    request: AdRequest(),
    rewardedAdLoadCallback: RewardedAdLoadCallback(
      onAdLoaded: (ad) {
        rewardedAd = ad;
        print('Rewarded ad loaded.');
      },
      onAdFailedToLoad: (error) {
        print('Failed to load rewarded ad: $error');
      },
    ),
  );
}

void showRewardedAd() {
  if (rewardedAd == null) {
    print('Rewarded ad not ready.');
    return;
  }
  rewardedAd!.fullScreenContentCallback = FullScreenContentCallback(
    onAdDismissedFullScreenContent: (ad) {
      ad.dispose();
      loadRewardedAd();
    },
    onAdFailedToShowFullScreenContent: (ad, error) {
      ad.dispose();
      print('Failed to show rewarded ad: $error');
      loadRewardedAd();
    },
  );
  rewardedAd!.show(onUserEarnedReward: (ad, reward) {
    print('User earned reward: ${reward.amount} ${reward.type}');
    // TODO: Grant reward in your app here.
  });
  rewardedAd = null;
}

⚠️ Important Tips for All Ads

  • Use test ad unit IDs during development to avoid AdMob policy violations.

  • Load interstitial and rewarded ads before showing them to prevent delays.

  • Dispose ads properly after use to free up resources.

  • Display ads at natural points to avoid frustrating users.

 

Leave a Comment

Your email address will not be published. Required fields are marked *