Skip to content

Instantly share code, notes, and snippets.

@rena2019
Created September 24, 2025 14:18
Show Gist options
  • Select an option

  • Save rena2019/dc7122a1021ac44570e9f4d90858bf14 to your computer and use it in GitHub Desktop.

Select an option

Save rena2019/dc7122a1021ac44570e9f4d90858bf14 to your computer and use it in GitHub Desktop.
Overlay Popup with Stream
import 'dart:async';
import 'package:flutter/material.dart';
//Overlay Popup with Stream
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) => MaterialApp(home: HomePage());
}
/* --- Beispiel-Datenmodell & Kommunikation --- */
class MyStreamData {
final double progress; // 0.0 - 1.0
final String? message;
MyStreamData(this.progress, {this.message});
}
class MyCommunication {
// Simulierter Stream, in realem Code würdest du hier echte Daten liefern
final StreamController<MyStreamData> _ctrl = StreamController.broadcast();
Stream<MyStreamData> get incomingStream => _ctrl.stream;
// Für Demo: starte simulation
void startSimulation() async {
for (int i = 0; i <= 10; i++) {
await Future.delayed(Duration(milliseconds: 400));
_ctrl.add(MyStreamData(i / 10, message: 'Step $i/10'));
}
await Future.delayed(Duration(milliseconds: 500));
_ctrl.add(MyStreamData(1.0, message: 'Fertig'));
}
void dispose() => _ctrl.close();
}
/* --- PopupMessage Widget-Klasse (zustandsbehaftet) --- */
class PopupMessage extends StatefulWidget {
final Stream<MyStreamData> progressStream;
final VoidCallback onClose;
final String title;
PopupMessage({
required this.progressStream,
required this.onClose,
this.title = 'Ladevorgang',
Key? key,
}) : super(key: key);
@override
_PopupMessageState createState() => _PopupMessageState();
}
class _PopupMessageState extends State<PopupMessage> {
late StreamSubscription<MyStreamData> _sub;
double _progress = 0.0;
String? _message;
@override
void initState() {
super.initState();
_sub = widget.progressStream.listen((data) {
setState(() {
_progress = data.progress.clamp(0.0, 1.0);
_message = data.message;
});
// Optional: automatisch schließen, wenn fertig
if (_progress >= 1.0) {
Future.delayed(Duration(milliseconds: 300), () {
widget.onClose();
});
}
}, onError: (err) {
// Fehlerbehandlung hier
});
}
@override
void dispose() {
_sub.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Material(
color: Colors.black54, // halbtransparenter Modal-Hintergrund
child: Center(
child: Container(
width: 320,
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
),
child: Column(
mainAxisSize: MainAxisSize.min, //vertical center
children: [
Text(widget.title, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
SizedBox(height: 12),
LinearProgressIndicator(value: _progress),
SizedBox(height: 12),
Text(_message ?? '${(_progress * 100).round()}%'),
SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(onPressed: widget.onClose, child: Text('Abbrechen')),
],
),
],
),
),
),
);
}
}
/* --- HomePage: zeigt wie OverlayEntry genutzt wird --- */
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final MyCommunication comm = MyCommunication();
OverlayEntry? _overlayEntry;
void _showPopup() {
if (_overlayEntry != null) return; // bereits sichtbar
_overlayEntry = OverlayEntry(
builder: (context) {
return PopupMessage(
progressStream: comm.incomingStream,
onClose: _removePopup,
title: 'Upload',
);
},
);
Overlay.of(context)!.insert(_overlayEntry!);
// Demo: starte Simulationsdaten
comm.startSimulation();
}
void _removePopup() {
_overlayEntry?.remove();
_overlayEntry = null;
}
@override
void dispose() {
comm.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Overlay Popup mit Stream')),
body: Center(
child: ElevatedButton(
onPressed: _showPopup,
child: Text('Zeige PopupMessage'),
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment