Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende Streams for Real-Time Flutter UIs | Asynchronous Dart in Flutter
Practice
Projects
Quizzes & Challenges
Quizzes
Challenges
/
Dart for Flutter Developers

bookStreams for Real-Time Flutter UIs

Dart Streams are a powerful way to handle asynchronous sequences of data. In Flutter, you use Streams to listen for real-time updates—such as user actions, network responses, or sensor data—and update your UI instantly as new events arrive. Unlike Future, which returns a single value, a Stream delivers many values over time, making it ideal for chat messages, search suggestions, or live feeds.

main.dart

main.dart

copy
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
import 'dart:async'; import 'package:flutter/material.dart'; void main() => runApp(StreamDemoApp()); class StreamDemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: StreamCounterWidget(), ); } } class StreamCounterWidget extends StatefulWidget { @override _StreamCounterWidgetState createState() => _StreamCounterWidgetState(); } class _StreamCounterWidgetState extends State<StreamCounterWidget> { final StreamController<int> _controller = StreamController<int>(); int _counter = 0; @override void initState() { super.initState(); // Emit a new value every second Timer.periodic(Duration(seconds: 1), (timer) { _controller.sink.add(++_counter); if (_counter >= 5) timer.cancel(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Stream Counter')), body: Center( child: StreamBuilder<int>( stream: _controller.stream, builder: (context, snapshot) { if (snapshot.hasData) { return Text('Counter: [${snapshot.data}', style: TextStyle(fontSize: 24)); } else { return Text('Waiting for data...', style: TextStyle(fontSize: 24)); } }, ), ), ); } @override void dispose() { _controller.close(); super.dispose(); } }

When you work with Streams in Flutter, you will often use a StreamController to add data to a stream and manage its lifecycle. Subscribing to a stream gives you a StreamSubscription, which you must manage carefully—especially in stateful widgets—to avoid resource leaks or unexpected behavior.

main.dart

main.dart

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
import 'dart:async'; import 'package:flutter/material.dart'; void main() => runApp(SubscriptionDemoApp()); class SubscriptionDemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: SubscriptionWidget(), ); } } class SubscriptionWidget extends StatefulWidget { @override _SubscriptionWidgetState createState() => _SubscriptionWidgetState(); } class _SubscriptionWidgetState extends State<SubscriptionWidget> { final StreamController<String> _controller = StreamController<String>(); StreamSubscription<String>? _subscription; String _latest = "No data"; @override void initState() { super.initState(); _subscription = _controller.stream.listen((data) { setState(() { _latest = data; }); }); // Simulate incoming data Future.delayed(Duration(seconds: 1), () { _controller.add("Hello from Stream!"); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('StreamSubscription Example')), body: Center(child: Text(_latest, style: TextStyle(fontSize: 24))), ); } @override void dispose() { _subscription?.cancel(); _controller.close(); super.dispose(); } }
Note
Note

Always cancel your StreamSubscriptions in the dispose method of a stateful widget. Failing to do so can cause memory leaks and unexpected behavior, as the widget may continue to listen to data even after it is removed from the widget tree.

question mark

Which statement about Streams in Flutter is correct?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 2. Capítulo 2

Pregunte a AI

expand

Pregunte a AI

ChatGPT

Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla

Suggested prompts:

What are some common use cases for Streams in Flutter?

How do I properly manage a StreamSubscription in a stateful widget?

Can you explain the difference between Stream and Future in more detail?

bookStreams for Real-Time Flutter UIs

Desliza para mostrar el menú

Dart Streams are a powerful way to handle asynchronous sequences of data. In Flutter, you use Streams to listen for real-time updates—such as user actions, network responses, or sensor data—and update your UI instantly as new events arrive. Unlike Future, which returns a single value, a Stream delivers many values over time, making it ideal for chat messages, search suggestions, or live feeds.

main.dart

main.dart

copy
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
import 'dart:async'; import 'package:flutter/material.dart'; void main() => runApp(StreamDemoApp()); class StreamDemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: StreamCounterWidget(), ); } } class StreamCounterWidget extends StatefulWidget { @override _StreamCounterWidgetState createState() => _StreamCounterWidgetState(); } class _StreamCounterWidgetState extends State<StreamCounterWidget> { final StreamController<int> _controller = StreamController<int>(); int _counter = 0; @override void initState() { super.initState(); // Emit a new value every second Timer.periodic(Duration(seconds: 1), (timer) { _controller.sink.add(++_counter); if (_counter >= 5) timer.cancel(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Stream Counter')), body: Center( child: StreamBuilder<int>( stream: _controller.stream, builder: (context, snapshot) { if (snapshot.hasData) { return Text('Counter: [${snapshot.data}', style: TextStyle(fontSize: 24)); } else { return Text('Waiting for data...', style: TextStyle(fontSize: 24)); } }, ), ), ); } @override void dispose() { _controller.close(); super.dispose(); } }

When you work with Streams in Flutter, you will often use a StreamController to add data to a stream and manage its lifecycle. Subscribing to a stream gives you a StreamSubscription, which you must manage carefully—especially in stateful widgets—to avoid resource leaks or unexpected behavior.

main.dart

main.dart

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
import 'dart:async'; import 'package:flutter/material.dart'; void main() => runApp(SubscriptionDemoApp()); class SubscriptionDemoApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: SubscriptionWidget(), ); } } class SubscriptionWidget extends StatefulWidget { @override _SubscriptionWidgetState createState() => _SubscriptionWidgetState(); } class _SubscriptionWidgetState extends State<SubscriptionWidget> { final StreamController<String> _controller = StreamController<String>(); StreamSubscription<String>? _subscription; String _latest = "No data"; @override void initState() { super.initState(); _subscription = _controller.stream.listen((data) { setState(() { _latest = data; }); }); // Simulate incoming data Future.delayed(Duration(seconds: 1), () { _controller.add("Hello from Stream!"); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('StreamSubscription Example')), body: Center(child: Text(_latest, style: TextStyle(fontSize: 24))), ); } @override void dispose() { _subscription?.cancel(); _controller.close(); super.dispose(); } }
Note
Note

Always cancel your StreamSubscriptions in the dispose method of a stateful widget. Failing to do so can cause memory leaks and unexpected behavior, as the widget may continue to listen to data even after it is removed from the widget tree.

question mark

Which statement about Streams in Flutter is correct?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 2. Capítulo 2
some-alt