toast_native_dev 0.0.11
toast_native_dev: ^0.0.11 copied to clipboard
Native toast notifications that appear above Flutter widgets and platform views using Android and iOS overlay layers.
toast_native_dev #
Native toast notifications for Flutter that render above Flutter widgets and platform views.
The plugin does not use Flutter OverlayEntry, ScaffoldMessenger, or Overlay.of(...) for rendering. Toasts are drawn by the native platform layer so they can stay visible above native views that may cover Flutter-rendered overlays.
Why #
Flutter toasts and overlays work normally above Flutter widgets. The problem starts when a screen contains native platform views: those views can sit outside or above Flutter's overlay stack, depending on the platform and composition mode. This package avoids that layer ordering issue by rendering toasts through native overlay surfaces:
| Platform | Native rendering layer |
|---|---|
| Android | A ComposeView attached to the Activity DecorView |
| iOS | One shared passthrough UIWindow on the active UIWindowScene |
Touches outside the toast pass through to the Flutter app, so the page remains usable while a toast is visible.
Install #
dependencies:
toast_native_dev: ^0.0.11
import 'package:toast_native_dev/toast_native_dev.dart';
Quick Start #
await showToast(
type: ToastType.success,
title: 'Profile saved',
);
Default behavior:
| Option | Default |
|---|---|
| Position | ToastPosition.top |
| Duration | NativeToastLength.short - 2 seconds |
| Background | Based on ToastType |
| Icon | Based on ToastType |
| Dismiss direction | up for top, down for bottom |
Custom Toast #
await showToast(
type: ToastType.warning,
title: 'Session expiring soon',
subtitle: 'Save your work',
options: const NativeToastOptions(
position: ToastPosition.bottom,
length: NativeToastLength.long,
),
);
API #
showToast #
Future<void> showToast({
required ToastType type,
String? title,
String? subtitle,
NativeToastOptions options = const NativeToastOptions(),
})
title and subtitle are optional. A null or blank value is not drawn. If both are missing, showToast does nothing.
The returned Future<void> completes after the native platform receives the request. It does not wait until the toast disappears.
ToastType #
| Value | Default color | Default icon |
|---|---|---|
ToastType.success |
0xff18A957 |
Check circle |
ToastType.error |
0xffFB2C36 |
Close circle |
ToastType.warning |
0xffF8B632 |
Info circle |
ToastType.info |
0xff969696 |
WiFi disconnect |
NativeToastOptions #
| Field | Type | Default | Description |
|---|---|---|---|
position |
ToastPosition |
ToastPosition.top |
Shows the toast at the top or bottom. |
length |
NativeToastLength |
NativeToastLength.short |
Auto-dismiss duration. |
bgColor |
Color? |
Type color | Overrides the default background color. |
icon |
NativeToastIcon? |
Type icon | Overrides or hides the icon. |
dismissDirection |
NativeToastDismissDirection? |
Based on position | Drag direction that dismisses the toast. |
ToastPosition #
| Value | Behavior |
|---|---|
ToastPosition.top |
Toasts stack downward from the top edge. |
ToastPosition.bottom |
Toasts stack upward from the bottom edge. The newest bottom toast stays closest to the bottom. |
NativeToastLength #
| Value | Duration |
|---|---|
NativeToastLength.short |
2 seconds |
NativeToastLength.medium |
4 seconds |
NativeToastLength.long |
6 seconds |
NativeToastLength.ages |
10 seconds |
NativeToastLength.never |
No auto-dismiss |
NativeToastLength.ms(int) |
Custom duration in milliseconds |
Custom durations must be positive. NativeToastLength.never is the only non-positive supported duration.
await showToast(
type: ToastType.success,
title: 'Saved',
options: const NativeToastOptions(
length: NativeToastLength.ms(1500),
),
);
NativeToastIcon #
| Value | Behavior |
|---|---|
NativeToastIcon.success({color}) |
Check circle. |
NativeToastIcon.error({color}) |
Close circle. |
NativeToastIcon.warning({color}) |
Info circle. |
NativeToastIcon.info({color}) |
WiFi disconnect. |
NativeToastIcon.none |
Hides the icon. |
Icons are drawn natively; no image assets are required.
Gestures #
| Gesture | Behavior |
|---|---|
Drag in dismissDirection |
Moves the toast with the finger. If dragged past the threshold, the toast dismisses. |
| Drag opposite direction | Movement is clamped, so the toast resists the wrong direction. |
| Touch and hold | Pauses the auto-dismiss timer. |
| Release after hold | Resumes the remaining auto-dismiss duration. |
Stacking #
Multiple toasts can be visible at the same time.
- Top toasts stack downward.
- Bottom toasts stack upward.
- Removing a toast rebuilds the stack offsets.
- Background taps pass through to Flutter on iOS.
Platform Support #
| Platform | Minimum |
|---|---|
| Android | API 21 |
| iOS | 13.0 |
Implementation Notes #
Dart #
Public API lives in lib/toast_native_dev.dart.
The MethodChannel is:
const MethodChannel('toast_native_dev/channel');
showToast sends these arguments to native code:
| Argument | Type |
|---|---|
type |
success, warning, error, or info |
title |
String (empty when omitted) |
subtitle |
String (empty when omitted) |
position |
top or bottom |
durationMs |
Duration in milliseconds (-1 = never auto-dismiss) |
color |
ARGB integer |
icon |
success, warning, error, info, or none |
iconColor |
ARGB integer |
dismissDirection |
up or down |
Android #
Android code lives in:
android/src/main/kotlin/dev/eqdevs/toast_native_dev/
The plugin attaches a single ComposeView to the Activity DecorView and renders all active toasts from a mutableStateListOf<ToastData>.
iOS #
iOS code lives in:
ios/Classes/NativeToastPlugin.swift
One shared passthrough UIWindow is attached to the active UIWindowScene. The window is above Flutter and native platform views, while touches outside the toast pass through to the app.
Development #
Analyze:
flutter analyze
Format:
dart format .
Unit tests (Dart + Android JUnit):
flutter test
cd example/android && ./gradlew :toast_native_dev:testDebugUnitTest
Native integration tests (needs a device or simulator):
cd example
flutter test integration_test/native_toast_test.dart
iOS XCTest (from example/ios, after pod install):
xcodebuild test -workspace Runner.xcworkspace -scheme Runner -destination 'platform=iOS Simulator,name=iPhone 17 Pro Max' -only-testing:RunnerTests
Run the example app:
cd example
flutter run
Build the iOS simulator example:
cd example
flutter build ios --simulator
License #
MIT - see LICENSE.