ads_core_flutter

ads_core_flutter is a mobile-first Flutter ads toolkit for Android and iOS. It wraps google_mobile_ads with a cleaner setup for banner, interstitial, rewarded, app open, and native templates.

Features

  • Android and iOS support
  • Google test IDs included for fast local testing
  • AdsController for preload/show flows
  • AdsBanner widget for pinned banner layouts
  • NativeAdPool and AdsNativeFeedItem for list/feed insertion
  • Example app included under example/

Installation

dependencies:
  ads_core_flutter: ^0.1.0

Native setup

Add your AdMob app IDs before release.

Android AndroidManifest.xml

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

iOS Info.plist

<key>GADApplicationIdentifier</key>
<string>ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy</string>

Android theme requirement (for native templates):

google_mobile_ads native templates use AppCompat widgets internally. Set both day and night app themes to an AppCompat (or Material) descendant.

<!-- android/app/src/main/res/values/styles.xml -->
<style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar" />
<style name="NormalTheme" parent="Theme.AppCompat.Light.NoActionBar" />
<!-- android/app/src/main/res/values-night/styles.xml -->
<style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar" />
<style name="NormalTheme" parent="Theme.AppCompat.Light.NoActionBar" />

Quick start

import 'package:ads_core_flutter/ads_core_flutter.dart';

final ads = AdsController(
  unitIds: const AdsPlatformUnitIds.googleTest(),
);

await ads.initialize();
await ads.preloadInterstitial();
await ads.preloadRewarded();
await ads.preloadAppOpen();

Banner:

Scaffold(
  bottomNavigationBar: AdsBanner(controller: ads),
);

Rewarded:

final shown = await ads.showRewardedIfReady(
  onRewarded: (reward) {
    debugPrint('Reward: ${reward.amount} ${reward.type}');
  },
);

Native feed:

final pool = ads.createNativeAdPool(
  layout: AdsNativeLayout.small(),
  maxConcurrentLoads: 2,
  maxAutoRetryAttempts: 2,
  retryBaseDelay: const Duration(seconds: 2),
);

AdsNativeFeedItem(
  pool: pool,
  position: 3,
)

Native layout presets:

final smallPool = ads.createNativeAdPool(
  layout: AdsNativeLayout.small(),
);

final mediumPool = ads.createNativeAdPool(
  layout: AdsNativeLayout.medium(),
);

small uses a tighter default content height to avoid extra empty space.

Troubleshooting

  • This AdWidget is already in the Widget tree
    • Ensure each feed insertion uses a unique slot position.
    • AdsNativeFeedItem now claims a slot internally and safely collapses duplicate slot widgets instead of crashing.
  • Ad failed to load: 0 (Internal error)
    • This is usually inventory/network/test-campaign behavior, not a crash.
    • Keep preload pressure low with maxConcurrentLoads and fewer preloaded positions.
  • AppCompatButton ... only be used with a Theme.AppCompat theme
    • Update both values/styles.xml and values-night/styles.xml to AppCompat/Material parents.

Production IDs

Replace AdsPlatformUnitIds.googleTest() with your own IDs:

const ids = AdsPlatformUnitIds(
  android: AdsUnitIds(
    banner: 'ca-app-pub-xxx/xxx',
    interstitial: 'ca-app-pub-xxx/xxx',
    native: 'ca-app-pub-xxx/xxx',
    appOpen: 'ca-app-pub-xxx/xxx',
    rewarded: 'ca-app-pub-xxx/xxx',
  ),
  ios: AdsUnitIds(
    banner: 'ca-app-pub-xxx/xxx',
    interstitial: 'ca-app-pub-xxx/xxx',
    native: 'ca-app-pub-xxx/xxx',
    appOpen: 'ca-app-pub-xxx/xxx',
    rewarded: 'ca-app-pub-xxx/xxx',
  ),
);

Example

Run the included demo:

cd example
flutter run

Libraries

ads_core_flutter