pangle_flutter 3.0.2 copy "pangle_flutter: ^3.0.2" to clipboard
pangle_flutter: ^3.0.2 copied to clipboard

A Flutter plugin that supports ByteDance Pangle SDK on Android and iOS. Such as Splash Ads, Rewarded Video Ads, etc.

English | 中文


3.0.2 #

Build Infrastructure #

Android

  • Upgraded Android Gradle Plugin: 8.11.1 → 9.0.1
  • Upgraded Gradle wrapper: 8.14 → 9.1.0
  • Upgraded Kotlin plugin: 2.2.20 → 2.3.20
  • Refactored android/build.gradle.kts: decoupled Kotlin compiler options via pluginManager.withPlugin so the library builds correctly regardless of Kotlin plugin presence; switched jvmToolchain to compilerOptions.jvmTarget (typed enum)
  • Added testOptions block with JUnit Platform support and per-test stdout/stderr logging
  • Example: switched compileSdk / targetSdk / versionCode / versionName to Flutter-provided values where applicable; fixed Gradle 9 Directory API usage in build.gradle.kts
  • Added AGP 9 + Flutter Gradle plugin compatibility flags to gradle.properties: android.newDsl=false, android.builtInKotlin=false

iOS

  • Migrated plugin source layout from ios/Classes/ to a proper Swift Package at ios/pangle_flutter/ (Sources/pangle_flutter/)
  • Removed legacy Obj-C bridge files (PangleFlutterPlugin.h / .m) — no longer needed under SPM
  • Updated pangle_flutter.podspec: source_files and resource_bundles paths now point to the new SPM layout
  • Example: removed CocoaPods integration (Pods xcconfig includes, Pods.xcodeproj workspace reference, all [CP] build phases); replaced with FlutterGeneratedPluginSwiftPackage as an XCLocalSwiftPackageReference
  • Example: added a "Prepare Flutter Framework" pre-action to the Xcode scheme so SPM builds correctly trigger Flutter's xcode_backend prepare step
  • Example: replaced CocoaPods xcconfig includes with explicit OTHER_LDFLAGS weak-framework flags for AppTrackingTransparency, CoreHaptics, CoreML, DeviceCheck
  • Example: merged Info-Debug.plist / Info-Release.plist into a single Info.plist

Dart / pubspec

  • Fixed iOS pluginClass in pubspec.yaml: PangleFlutterPluginSwiftPangleFlutterPlugin
  • Relaxed Dart SDK constraint: ^3.11.5'>=3.0.0 <4.0.0'
  • Raised minimum Flutter version: 3.3.03.10.0

3.0.1 #

New Features #

  • Mediation support (useMediation): added useMediation parameter to both IOSConfig and AndroidConfig. Set to true to enable Pangle's GroMore mediation layer.
await pangle.init(
  iOS: const IOSConfig(appId: kIOSAppId, useMediation: true),
  android: const AndroidConfig(appId: kAndroidAppId, useMediation: true),
);

SDK Dependency Updates #

  • iOS: switched from Ads-CN ~> 7.0 to Ads-CN-Beta/BUAdSDK ~> 7.0 + Ads-CN-Beta/CSJMediation ~> 7.0
  • Android: switched from com.pangle.cn:ads-sdk-pro to com.pangle_beta.cn:mediation-sdk

Example App #

  • Test Measurement Suite: integrated BUAdTestMeasurementManager on both iOS and Android. Tap the 🐛 button (debug builds only) to launch the Pangle test panel.
  • Theme picker: added SDK theme switcher (light / dark) as the first item on the home page.
  • Setup page: SDK initialisation is now done on a dedicated SetupPage before entering the main menu.

3.0.0 #

New Features #

Draw Ad (Vertical Full-Screen Video)

TikTok-style vertically scrollable video ads. Load a batch of IDs, then display each one inside a full-screen PageView.

// 1. Load
final PangleDrawAd drawAd = await pangle.loadDrawAd(
  iOS: IOSDrawConfig(slotId: kDrawId, adCount: 3),
  android: AndroidDrawConfig(slotId: kDrawId, adCount: 2),
);

// 2. Display — embed in a full-screen PageView
DrawView(
  id: drawAd.data.first,
  onClick: () {},
  onShow: () {},
  onRenderFail: (code, msg) {},
)

// 3. Clean up
await pangle.removeDrawAd(drawAd.data);

Stream Ad (Custom Player)

Returns video URL + metadata for use with your own video player. No SDK-rendered view required.

final PangleStreamAd streamAd = await pangle.loadStreamAd(
  iOS: IOSStreamConfig(slotId: kStreamId),
  android: AndroidStreamConfig(slotId: kStreamId),
);
for (final StreamAdItem item in streamAd.data) {
  // item.videoUrl, item.title, item.imageUrl, item.videoDuration, etc.
}

EcMall Ad (Shopping / Native Ad)

Commerce-integrated native ad rendered as a platform view. Must be wrapped in a size-constraining widget.

SizedBox(
  width: 600,
  height: 257,
  child: EcMallView(
    slotId: kEcMallId,
    width: 600,
    height: 257,
    onClick: () {},
    onError: (code, msg) {},
  ),
)

Feed Icon Ad

Icon-sized feed ad for compact grid or list layouts. Rendered with the standard FeedView widget.

final PangleAd iconAd = await pangle.loadFeedIconAd(
  android: AndroidFeedIconConfig(slotId: kFeedIconId),
);
FeedView(id: iconAd.data.first)

Half-Screen Splash (Android)

Show a splash ad occupying ~4/5 of the screen height instead of full-screen. Android only.

await pangle.loadSplashAd(
  android: AndroidSplashConfig(slotId: kSplashId, isHalfSize: true),
  iOS: IOSSplashConfig(slotId: kSplashId),
);

  • [Dart] BannerView and FeedView now apply AspectRatio internally based on expressSize (when height > 0). No need to wrap them in an external AspectRatio or manually set a matching container height. FeedView accepts a new optional expressSize parameter — pass the same value used in loadFeedAd.

Bug Fixes #

  • [Android] SDK is now initialised with applicationContext instead of the activity context, eliminating a class of context-leak issues on process restart. Splash ad no longer requires a FragmentActivity host — any Activity works.
  • [iOS] Fixed critical bug: interstitial event sink was incorrectly mapped to the fullscreen sink in PangleEventStreamHandler, causing interstitial callbacks to be silently dropped
  • [iOS] Fixed dead initWithMessenger static method in FeedViewFactory that returned a BannerViewFactory instance instead of FeedViewFactory
  • [iOS] Fixed double force-unwrap (!!) when resolving the key window in FLTView

Safety & Stability #

  • [iOS] Replaced [unowned self] captures with [weak self] + guard let self in all async closures (PangleAdManager, FLTRewardedVideoExpressAdTask, FLTFullscreenVideoExpressAdTask) to prevent potential crashes on deallocation
  • [iOS] Replaced force casts (as!, !) with safe guard let optional binding throughout (FLTNativeExpressAdTask, FLTBannerView, FLTBannerView.loadExpressAd)

API Modernization #

  • [iOS] Replaced deprecated UIApplication.shared.windows / keyWindow with the connectedScenes-based approach, compatible with multi-window and scene-based UIKit
  • [iOS] Updated swift_version from 5.0 to 5.9 in the podspec
  • [Android] Replaced deprecated .values()[index] enum access with .entries.getOrNull(index) with a safe default fallback (PangleLoadingType, PangleOrientation, PangleTitleBarTheme)
  • [Android] Replaced deprecated systemUiVisibility with WindowInsetsController on API 30+; kept a backward-compatible path for API 24–29
  • [Android] Added const modifier to package-level constants in PangleFlutterPlugin

Performance #

  • [Android] Cached Handler(Looper.getMainLooper()) as a class field in view classes (FlutterBannerView, FlutterFeedView, FlutterSplashView, FlutterEcMallView) instead of allocating a new instance per call
  • [Dart] Changed top-level screen dimension variables (kPangleScreenWidth, kPangleScreenHeight) to late final to defer initialization until first access

New Features #

Ad Load / Show Separation — RewardedAd & FullscreenAd

Rewarded and fullscreen video ads now have dedicated wrapper objects that cleanly separate loading from showing. load() is a static factory that resolves only on success and throws AdLoadException on failure — no more checking result.code manually.

try {
  final ad = await RewardedAd.load(
    slotId: 'your_slot_id',
    iOS: const IOSRewardedVideoConfig(slotId: 'xxx'),
    android: AndroidRewardedVideoConfig(slotId: 'xxx'),
  );
  // Reaching here guarantees load succeeded
  final result = await ad.show(
    onEvent: (event) {
      if (event case AdRewardEvent(:final verified) when verified) {
        grantReward();
      }
    },
  );
} on AdLoadException catch (e) {
  debugPrint('load failed: $e');
}

FullscreenAd follows the same pattern with FullscreenAd.load() / ad.show().

Preload Pools — RewardedAdPool & FullscreenAdPool

Singleton pool managers handle preloading, caching, and auto-refill after each show.

// Configure once at startup
await RewardedAdPool.instance.configure(
  slotId: 'your_slot_id',
  poolSize: 2,           // keep 2 ads ready
  autoRefill: true,      // reload after each show
  iOS: const IOSRewardedVideoConfig(slotId: 'xxx'),
  android: AndroidRewardedVideoConfig(slotId: 'xxx'),
);

if (await RewardedAdPool.instance.isReady('your_slot_id')) {
  await RewardedAdPool.instance.show(
    slotId: 'your_slot_id',
    onEvent: (event) { ... },
  );
}

Type-safe Ad Events — PangleAdEvent sealed class

All native event strings are now mapped to a sealed class hierarchy, enabling exhaustive switch matching:

switch (event) {
  case AdRewardEvent(:final verified): ...
  case AdClosedEvent():               ...
  case AdErrorEvent():                ...
  default:                            ...
}

Available subtypes: AdLoadedEvent, AdCachedEvent, AdShownEvent, AdSkippedEvent, AdClickedEvent, AdCompletedEvent, AdClosedEvent, AdErrorEvent, AdRenderFailedEvent, AdRenderSuccessEvent, AdRewardEvent, AdUnknownEvent.

Native: show and has methods

  • [Android/iOS] Added showRewardedVideoAd(slotId) and showFullscreenVideoAd(slotId) method channel calls — show a cached ad without triggering a new load.
  • [Android/iOS] Added hasRewardedVideoAd(slotId) and hasFullscreenVideoAd(slotId) — query whether a non-expired cached ad is available.
  • [Android] PangleAdManager: added hasRewardedVideoAd() and hasFullscreenVideoAd() with the same expiration check as showRewardedVideoAd().
  • [iOS] PangleAdManager: added hasRewardedVideoAd(_:) and hasFullscreenVideoAd(_:) protected by adQueue.sync.

SplashView

  • [iOS/Android/Dart] Differentiated SplashView error callbacks: onRenderFail (render failure) and onError (load failure) — consistent with the existing BannerView pattern
  • [SplashView] Added onRenderFail callback parameter to the SplashView widget

Deprecations #

  • pangle.loadRewardedVideoAd() — use RewardedAd.load() / RewardedAdPool instead.
  • pangle.loadFullscreenVideoAd() — use FullscreenAd.load() / FullscreenAdPool instead.
  • PangleLoadingType — now an internal implementation detail; do not reference in application code.

Improvements #

  • [Dart] IOSRewardedVideoConfig, IOSFullscreenVideoConfig, AndroidRewardedVideoConfig, AndroidFullscreenVideoConfig — added copyWith() methods.
  • [iOS] Simplified FLTView.hitTest: removed the fragile FlutterOverlayView class-name detection (a no-op since Flutter 3+ switched to TLHC rendering). touchableBounds now directly restricts which areas of the native ad view receive touch events.
  • [iOS] Cleaned up UIUtil: removed isOverlay, findTargetView, and findTargetOverlayView (dead code in Flutter 3+ TLHC mode)
  • [Android] SurfaceAndroidBannerView, SurfaceAndroidFeedView, SurfaceAndroidSplashView: removed the hybridComposition parameter; all three now exclusively use TLHC (initSurfaceAndroidView). The Hybrid Composition path (initExpensiveAndroidView) has been removed. AndroidViewMixin.createView simplified accordingly.

Code Cleanup #

  • [Android] Removed deprecated NativeSplashDialog implementation; splash dialog now exclusively uses the AndroidX-based SupportSplashDialog
  • [Android] Removed dead code branches for API level < 24 (below minSdk)
  • [Android] Removed redundant get() = field getter from ttAdNative in PangleAdManager

Dart / Flutter Modernization #

  • [Dart] Fixed Future<dynamic> return type on internal method-call handlers in feedview_method_channel.dart and bannerview_method_channel.dartFuture<void>
  • [Dart] Added explicit void return type to the three public typedefs (PangleSplashCloseTypeCallback, PangleMessageCallback, PangleOptionCallback) in util.dart
  • [Dart] Breaking: Renamed PangleOrientation.veriticalPangleOrientation.vertical (typo fix). Update any usages accordingly. Kotlin-side PangleOrientation.veritical renamed to PangleOrientation.vertical as well; ordinal values are unchanged.
  • [Dart] Replaced unsafe List.values[index] enum lookups with .elementAtOrNull() + safe default in splashview_method_channel.dart, model.dart, and pangle_plugin.dart
  • [Dart] Removed dead fields (_bannerViewPlatformController, _feedViewPlatformController, _splashViewPlatformController, _platformCallbacksHandler, _widget) and the no-op _updateWidget method from BannerViewController, FeedViewController, and SplashViewController; removed unused dart:async import from all three view files
  • [Example] Updated MediaQuery.of(context).size.widthMediaQuery.sizeOf(context).width in feed_page.dart

Ad Loading & Caching #

  • [Android] FlutterFeedView now fires onRenderFail(code=-1) to Dart when the requested ad is not found in the cache, instead of silently showing a blank view
  • [Android] FlutterFeedView.dispose() now calls removeExpressAd() to properly destroy the backing TTNativeExpressAd and prevent memory leaks when the Flutter widget is removed
  • [iOS] FLTFeedView.deinit now calls PangleAdManager.shared.removeExpressAd() to release the cached BUNativeExpressAdView when the platform view is destroyed
  • [iOS] FeedView.loadExpressAd() now fires onRenderFail(code=-1) to Dart when the ad is not found in the cache (mirrors the Android behavior above)
  • [iOS] Added CachedVideoAd wrapper struct with a 30-minute TTL for rewarded and fullscreen video ad caches in PangleAdManager. Expired entries are purged before each show attempt, aligning iOS behavior with Android's SDK-provided expirationTimestamp check
  • [iOS] removeExpressAd() — removed force-unwrap (key!), added @discardableResult

2.0.1 #

  • Optimize the use of Hybrid Composition

2.0.0 #

  • Upgrade ads sdk to 5.0+.
  • Adaptation method for removing overseas sdk
  • Remove insertion ads implementation (according to the document has been taken over by fullscreen ads, need to change the original call method to loadFullscreenVideoAd)
  • loadBannerAd has been adapted to use NativeAd implementation.
  • Fixed and optimized the open screen ad implementation

1.9.7 #

  • Fix analysis issues.

1.9.2 #

  • Fix [#87], deprecated method.

1.9.1 #

  • Optimize README (Clickthrough)

1.9.0 #

  • Fix click through problem on iOS
  • Remove "updateTouchableBounds" & "updateRestrictedBounds"
  • Add "addTouchableBounds" & "clearTouchableBounds" (extra click areas)

1.8.0 #

  • Adapt pangle SDK 4.7+ (Android & iOS)
  • [SplashView] Remove "onSkip" & "onTimeOver", add "onClose"
  • [SplashView] Fix "expressSize" not working on Android

1.7.0 #

  • Adapt pangle SDK 4.6+ (Android & iOS)
  • Adapt flutter 3.0.0
  • Add getDeviceInfo method

1.6.0 #

  • Adapt pangle SDK 4.3+ (Android & iOS)
  • Delete the splashButtonType param in AndroidSplashConfig and IOSSplashConfig
  • Delete the downloadType param in config_android.dart
  • Add gdpr,idfa params (IOSConfig)
  • Add openGDPRPrivacy method (iOS)

1.5.0+1 #

  • Release

1.5.0+1-beta #

  • Add useHybridComposition param (AndroidSplashView, AndroidBannerView, AndroidFeedView)

1.5.0-beta #

  • Update ad sdk
    • Android: Delete the rewardName and rewardAmount params in AndroidRewardedVideoConfig
    • iOS: Delete the isPaidApp param in IOSConfig

1.4.7 #

  • Fix the type conversion problem in FLTSplashView

1.4.6 #

  • The useTextureView property defaults to true (pangle.init(...))
  • Optimize gradle dependency library version limit
  • Added callbacks for interstitial, full-screen video, and rewarded video events

1.4.5 #

  • Fixed the issue that the onLoad of SplashView in iOS does not call back
  • Fix that the initialization parameter isPaidApp in iOS was incorrectly written as coppa
  • Optimized the problem that SplashView in iOS cannot adapt to the screen size due to the SDK upgrade, and added PangleExpressSize to configure the display size

1.4.4 #

  • Add onLoad callback for SplashView when an ad is loaded.

1.4.3 #

  • Downgrade kotlin's version

1.4.2 #

  • Migrating the plugin to the V2 embedding

1.4.1 #

  • Fix splashButtonType not work(IOSSplashConfig)

1.4.0 #

  • Upgrade android sdk version to 3.9.0.5, upgrade ios sdk version to 3.9+
  • Add new option for requesting ads(clickable area & downloading type popup dialog)

1.3.0 #

  • Upgrade android sdk version to 3.9.0.0, upgrade ios sdk version to 3.8+
  • Remove open_ad_sdk module, use maven repository instead of aar package
  • Optimize example

1.2.0 #

  • Adapt ads sdk(Android 3.8.0.0, iOS 3.7.0.5)
  • Fix FeedView's onDislike not callback on iOS

1.1.0 #

  • Adapt pangle overseas android sdk

1.0.1 #

  • Solve build packages failed (remove unrelated files)

1.0.0 #

  • null-safety

0.10.1 #

  • Remove Self-rendering ads support(Remove parameter isExpress
  • Optimize loading rewarded video & fullscreen video ads
  • Fix #20
  • Refactor BannerView, FeedView, SplashView
  • Add pangle.removeFeedAd() interface (Remove caches of feed ads)

0.9.1 #

  • Adapt to open_ad_sdk 3.5.0.0 for Android. iOS are not affected

0.8.2 #

  • Fix property tolerateTimeout type cast error
  • Fix example's Podfile has not joined plugin pangle_flutter

0.8.1 #

  • Adapt to pangle sdk 3.4+ (part class is removed, part of the property is out of date)
  • PangleResult add property verify

0.7.1 #

  • Upgrade min dependency version of Bytedance-UnionAD to 3.3

0.6.5 #

  • Adapt to onRewardVerify/nativeExpressRewardedVideoAdServerRewardDidSucceed callback parameters for reward video

0.6.4 #

  • Fix exception when BannerView & FeedView dispose

0.6.3 #

  • Optimize static analysis

0.6.2 #

  • Support custom splash ads [#10]
  • Upgrade pangle sdk

0.6.1 #

  • Fix rendering banner more than 5 seconds
  • Rename PangleFeedAd to PangleAd
  • Add interval for BannerView

0.5.1 #

  • Remove loadAwait
  • Adapt to open_ad_sdk 3.3.0.0
  • Podspec uses 'Bytedance-UnionAD', '~>3.2'

0.4.3 #

  • Add click action conflict solution for iOS
  • Add callback for splash ads
  • Fix bugs

0.4.2 #

  • Adds isUserInteractionEnabled attribute for iOS config
  • Fix rewarded video & fullscreen video callback crashed on Android.

0.4.1 #

  • Breaking changes.
  • Replace method returning type Map to PangleResult
  • Support iOS 14 for request tracking authorization

0.3.6 #

  • Fix feed express view for ios not works.

0.3.5 #

  • Refactor Android & iOS implementation.
  • Fix the memory leak of loading rewarded video ads & fullscreen video ads.
  • Optimize callback messages for requesting various ads.

0.3.4 #

  • On flutter android sdk, support registerWith method to load this plugin.
  • Rename loadRewardVideoAd to loadRewardedVideoAd.

0.3.3 #

  • Remove third party image loading framework dependency from Android & iOS.

0.3.2 #

  • Downgrade Bytedance-UnionAD to v3.2.5.1.

0.3.1 #

  • Adapt open_ad_sdkto v3.2.5.1.
  • Fix sdk printing a lot of log issue. (#7)

0.2.1 #

  • Update Bytedance-UnionAD to v3.2.5.1.
  • Update open_ad_sdk to v3.2.5.0.
  • New expressSize parameter to request ads. ()(The previous releases make ads dislocation & rendering incompletely )
  • Fix BannerViewFeedView touch events not work on iOS.

0.1.11 #

  • Splash ads loadAwait function.
  • Interestitial ads callbacks after closing.

0.1.10 #

  • Support setting the size of feed express ads, banner ads.

0.1.9 #

  • Fix the height of ConstraintLayout's Group widget not working.

0.1.8 #

  • Optimize BannerView, makes its config null safety.
  • Use new config class name.

0.1.7 #

  • Fix rewarded video ads callback not works.
  • Support fullscreen video ads.

0.1.6 #

  • Fix feed ads showing incorrect height.
  • Support preloading rewarded video ads.

0.1.5 #

  • Refactor the ads loading logic of iOS.
  • Support splash express ads (No test), rewarded video express ads.

0.1.4 #

  • Fix feed ads loading issue on Android.

0.1.3 #

  • Support express feed ads.
  • Optimize BannerView,FeedView (Using GlobalObjectKey to prevent destroying PlatformView ).

0.1.2 #

  • Support template rendering of interstitial ads & banner ads.
  • Optimize BannerView, FeedView removing logic.

0.1.1 #

  • Add interstitial ads.
  • Make android native permission request deprecated.

0.0.6 #

  • Remove the weak reference call of FlutterResult.

0.0.5 #

  • Add the default implemention of removing FeedView, BannerView.

0.0.4 #

  • Use ConstraintLayout to layout ads on Android.
  • Optimize FeedView, BannerView loading logic.

0.0.3 #

  • Formats project files.

0.0.2 #

  • Fixes the issues of Dart Analysis.

0.0.1 #

  • Init Splash Ads, Rewarded Video Ads, Banner Ads, Feed Ads.
32
likes
160
points
922
downloads

Documentation

API reference

Publisher

verified publisher2140s.com

Weekly Downloads

A Flutter plugin that supports ByteDance Pangle SDK on Android and iOS. Such as Splash Ads, Rewarded Video Ads, etc.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on pangle_flutter

Packages that implement pangle_flutter