One of the cornerstones of Flutter’s magic lies in its reactive approach, powered by the concepts of reactivity and streams. Let’s understand how streams wwork and build a simple chat app in Flutter.
What about Streams?
Streams are just a continous flow of data. In Flutter, streams provide a powerful way to handle asynchronous events and data flows.They act as a pipeline that emits a sequence of asynchronous data over time. This means you can listen to a stream and react to events as they occur, making your apps dynamic and responsive.
- Streams: An asynchronous sequence of data events.
- Subscription: The act of listening to a stream for events.
- Sinks: A way to add data to a stream.
- Controllers: Objects that manage a stream’s lifecycle and data flow.
Let’s build a simple chat app in flutter to understand the streams:
- Fetching Chat Messages:
Stream<List<Message>> getMessages() async* {
// Simulate fetching messages from a server
await Future.delayed(Duration(seconds: 2));
yield [Message("Hello!"), Message("How are you?")];
await Future.delayed(Duration(seconds: 3));
yield [Message("I'm doing well, thanks!")];
}
- Displaying Messages:
StreamBuilder<List<Message>>(
stream: getMessages(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
return Text(snapshot.data![index].text);
},
);
} else if (snapshot.hasError) {
return Text("Error: ${snapshot.error}");
} else {
return Center(child: CircularProgressIndicator());
}
},
)
- Sending Messages:
// Create a stream controller for outgoing messages
final _messageController = StreamController<Message>();
// Add a message to the stream
_messageController.sink.add(Message("New message!"));
// Close the stream when finished
_messageController.close();
- Handling User Inputs:
TextField(
onChanged: (text) {
// Send a new message when the user presses enter
if (text.endsWith('\n')) {
_messageController.sink.add(Message(text));
}
},
)
Additional Stream Features
- Transformation: Modify data as it flows through a stream (e.g., filtering, mapping).
- Error Handling: Gracefully handles errors that occur within a stream.
- Combination: Combine multiple streams into a single stream (e.g., merging, concatenating).
Conclusion
Streams are a fundamental concept in Flutter app development. By understanding streams, you can build apps that react gracefully to changes and provide a seamless user experience.