Skip to content

Instantly share code, notes, and snippets.

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

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

Select an option

Save rena2019/b9d3d78f2b849cbfcf1d7d4e9b486fa9 to your computer and use it in GitHub Desktop.
Progress Popup Widget with Stream
import 'dart:async';
import 'package:flutter/material.dart';
//Progress Popup Widget with Stream
/// Beispiel-Datenmodell, das vom Stream gesendet wird.
class MyStreamData {
final double progress; // 0.0 .. 1.0
final String? message;
final bool done;
MyStreamData({required this.progress, this.message, this.done = false});
}
/// Kommunikation-Klasse, die einen Stream erzeugt.
/// In der Praxis kommt der Stream z.B. von WebSocket, Isolate, HTTP-Upload-Progress etc.
class MyCommunication {
final StreamController<MyStreamData> _controller = StreamController.broadcast();
Stream<MyStreamData> get incomingStream => _controller.stream;
/// Beispiel: startet eine simulierte Progress-Übertragung
void startSimulatedTransfer({Duration step = const Duration(milliseconds: 300)}) {
double p = 0.0;
Timer.periodic(step, (t) {
p += 0.05;
if (p >= 1.0) {
_controller.add(MyStreamData(progress: 1.0, message: 'Fertig', done: true));
t.cancel();
return;
}
_controller.add(MyStreamData(progress: p, message: 'Lade ${ (p*100).round() }%'));
});
}
void dispose() {
_controller.close();
}
}
/// PopupMessage Widget zeigt eine simple Card mit ProgressBar und Text.
/// Es verwaltet eine StreamSubscription<MyStreamData> und aktualisiert State.
class PopupMessage extends StatefulWidget {
final Stream<MyStreamData> stream;
final VoidCallback? onDone;
const PopupMessage({Key? key, required this.stream, this.onDone}) : super(key: key);
@override
State<PopupMessage> createState() => _PopupMessageState();
}
class _PopupMessageState extends State<PopupMessage> {
late StreamSubscription<MyStreamData> _sub;
double _progress = 0.0;
String _text = 'Warte...';
bool _visible = true;
@override
void initState() {
super.initState();
_sub = widget.stream.listen((data) {
// Aktualisiere UI bei neuen Daten
setState(() {
_progress = data.progress.clamp(0.0, 1.0);
if (data.message != null) _text = data.message!;
if (data.done) {
_visible = false;
}
});
// optional: Callback informieren
if (data.done) widget.onDone?.call();
}, onError: (e) {
setState(() {
_text = 'Fehler: $e';
_visible = false;
});
}, onDone: () {
setState(() {
_visible = false;
});
});
}
@override
void dispose() {
_sub.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (!_visible) return const SizedBox.shrink();
return Center(
child: Material(
color: Colors.transparent,
child: Card(
elevation: 8,
child: SizedBox(
width: 300,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(_text),
const SizedBox(height: 12),
LinearProgressIndicator(value: _progress),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text('${(_progress * 100).round()}%'),
],
),
],
),
),
),
),
),
);
}
}
/// Minimaler demo App, die PopupMessage in einem Stack zeigt.
class DemoApp extends StatefulWidget {
@override
State<DemoApp> createState() => _DemoAppState();
}
class _DemoAppState extends State<DemoApp> {
final MyCommunication comm = MyCommunication();
bool _showPopup = false;
@override
void dispose() {
comm.dispose();
super.dispose();
}
void _start() {
setState(() => _showPopup = true);
comm.startSimulatedTransfer();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Popup Progress Demo')),
body: Stack(
children: [
Center(
child: ElevatedButton(
onPressed: _start,
child: const Text('Starte Transfer'),
),
),
if (_showPopup)
PopupMessage(
stream: comm.incomingStream,
onDone: () {
// Popup nach kurzer Verzögerung schließen
Future.delayed(const Duration(milliseconds: 400), () {
setState(() => _showPopup = false);
});
},
),
],
),
),
);
}
}
void main() => runApp(DemoApp());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment