overlay_pop_up
A new Flutter plugin to display pop ups or screens over other apps in Android even when app is closed or killed.
Demo
Android
add this to your AndroidManifest.xml
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application>
...
<service
android:name="com.requiemz.overlay_pop_up.OverlayService"
android:exported="false" />
</application>
Android 14
applications that target SDK 34 and use foreground service should include foregroundServiceType attribute(see documentation).
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application>
...
<service
android:name="com.requiemz.overlay_pop_up.OverlayService"
android:exported="false"
<!-- add this -->
android:foregroundServiceType="camera, dataSync, location, etc" />
</application>
Flutter implementation
configure your main.dart entry point a widget to display (make sure to add @pragma('vm:entry-point'))
NOTE: Now you can pass as parameter the dart entry point method name when showOverlay is called
@pragma("vm:entry-point")
void overlayPopUp() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: Text('Hello Pub.dev!'),
));
}
Overlay Methods
returns true when overlay permission is alreary granted if permission is not granted then open app settings
await OverlayPopUp.requestPermission();
returns true or false according to permission status
await OverlayPopUp.checkPermission();
display your overlay and return true if is showed
PARAMS
-
heightis not required by default is MATCH_PARENT -
widthis not required by default is MATCH_PARENT -
verticalAlignmentis not required by default is CENTER for more info see: developer.android.com/reference/android/view/Gravity -
horizontalAlignmentis not required by default is CENTER for more info see: developer.android.com/reference/android/view/Gravity -
backgroundBehaviorby default is focusable flag that is you can take focus inside a overlay for example inside a textfield andtapThroughyou can tap through the overlay background even if has MATCH_PARENT sizes. -
screenOrientationby default orientation is portrait. -
closeWhenTapBackButtonby default when user presses back button the overlay no has any action if you pass true then back button will close overlay. -
isDraggableby default is false therefore the overlay can“t be dragged. -
swipeToDismissby default is false. When enabled, users can drag the overlay to a drop zone (trash icon) at the bottom of the screen to dismiss it. Features include:- Drop zone with trash icon appears when dragging starts
- Overlay shrinks when entering drop zone area
- Pulse animation on drop zone when overlay is nearby
- Smooth dismiss animation when released in drop zone
- Works together with
isDraggablefor free movement in all directions
-
entryPointMethodNameby default is 'overlayPopUp' if you want you can change itawait OverlayPopUp.showOverlay( width: 300, height: 350, isDraggable: true, swipeToDismiss: true, // Enable swipe to dismiss );returns true if overlay closed correctly or already is closed
await OverlayPopUp.closeOverlay();returns the overlay status true = open, false = closed
await OverlayPopUp.isActive();returns the last overlay position if drag is enabled
await OverlayPopUp.getOverlayPosition();
Bidirectional Messaging
Send Data from Main App to Overlay
// From main app - send to overlay
await OverlayPopUp.sendToOverlay({'data': 'hello from main app!'});
await OverlayPopUp.sendToOverlay('hello');
Send Data from Overlay to Main App
// From overlay widget - send to main app
await OverlayPopUp.sendToMainApp({'from': 'overlay', 'message': 'Hello!'});
Receive Data in Main App (from Overlay)
// In your main app - listen for messages FROM overlay
StreamSubscription? listener;
@override
void initState() {
super.initState();
// Initialize message handler early
OverlayPopUp.initializeMessageHandler();
// Listen for messages from overlay
listener = OverlayPopUp.dataListener?.listen((data) {
print('Received from overlay: $data');
});
}
@override
void dispose() {
listener?.cancel();
super.dispose();
}
Receive Data in Overlay Widget (from Main App)
// In your overlay widget - listen for messages FROM main app
StreamBuilder(
stream: OverlayPopUp.overlayDataListener, // Use overlayDataListener here!
builder: (context, snapshot) {
return Text(snapshot.data?['message'] ?? 'No data');
},
)
Summary
| Location | Send Method | Receive Stream |
|---|---|---|
| Main App | sendToOverlay() |
dataListener (receives from overlay) |
| Overlay Widget | sendToMainApp() |
overlayDataListener (receives from main app) |

