Flutter StreamBuilder examples (2021)

Last updated on March 9, 2021 A Goodman Loading... Post a comment

The StreamBuilder widget is used in many kinds of Flutter applications, especially chat applications, social networks, real-time content updates, etc. In this article, we will go over 2 complete examples of implementing StreamBuilder: the first example is a real-time clock app and the second one is a demo chat app.

Overview

StreamBuilder is a widget that builds itself based on the latest snapshot of interaction with a stream.

Constructor:

StreamBuilder({
  Key? key, 
  T? initialData, 
  Stream<T>? stream, 
  required AsyncWidgetBuilder<T> builder
})

Main arguments:

  • builder: The build strategy currently used by this builder.
  • stream: The asynchronous computation to which this builder is currently connected, possibly null. When changed, the current summary is updated.

Understanding async* and yield

In the following example, you will notice these keywords: async* and yield. They all keywords used in generator functions.

A generator function is a function that produces a sequence of values (in contrast to regular functions that return a single value) and is often used with Stream.

Yield is a keyword that “returns” a single value to the sequence but does not stop the generator function.

Example 1: Real-time Clock App

Preview

This app displays a real-time clock in the center of the screen.

The Code

Here’s the full source code in main.dart file:

// main.dart
import 'package:flutter/material.dart';
import 'dart:async';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  bool _running = true;

  Stream<String> _clock() async* {
    // This loop will run forever because _running is always true
    while (_running) {
      await Future<void>.delayed(Duration(seconds: 1));
      DateTime _now = DateTime.now();
      // This will be displayed on the screen as current time
      yield "${_now.hour} : ${_now.minute} : ${_now.second}";
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kindacode.com'),
      ),
      body: Center(
        child: StreamBuilder(
          stream: _clock(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return CircularProgressIndicator();
            }
            return Text(
              snapshot.data,
              style: TextStyle(fontSize: 50, color: Colors.blue),
            );
          },
        ),
      ),
    );
  }
}

Example 2: Demo Chat App

This example is too simple compared to a real chat application, but it is a good thing to help you get a better understanding on how to use StreamBuilder.

Preview

The Code

// main.dart
import 'package:flutter/material.dart';
import 'dart:async';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // This list holds the conversation
  List<Map<String, String>> _chatMessages = [];

  // More messages added to the _chatMessages over time
  Stream<List<Map<String, String>>> _chat() async* {
    await Future<void>.delayed(Duration(seconds: 3));
    _chatMessages.add({"user_name": "Trump", "message": "Hello"});
    yield _chatMessages;

    await Future<void>.delayed(Duration(seconds: 3));
    _chatMessages.add({"user_name": "Biden", "message": "Hi baby"});
    yield _chatMessages;

    await Future<void>.delayed(Duration(seconds: 3));
    _chatMessages.add({
      "user_name": "Trump",
      "message": "Would you like to have dinner with me?"
    });
    yield _chatMessages;

    await Future<void>.delayed(Duration(seconds: 3));
    _chatMessages.add({
      "user_name": "Biden",
      "message": "Great. I am very happy to accompany you."
    });
    yield _chatMessages;

    await Future<void>.delayed(Duration(seconds: 3));
    _chatMessages
        .add({"user_name": "Trump", "message": "Nice. I love you, my honney!"});
    yield _chatMessages;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kindacode.com'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(30),
        child: StreamBuilder(
          stream: _chat(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (context, index) {
                  return ListTile(
                    leading: Text(
                      snapshot.data[index]["user_name"],
                      style:
                          TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
                    ),
                    title: Text(
                      snapshot.data[index]["message"],
                      style: TextStyle(
                          fontSize: 20,
                          color: snapshot.data[index]['user_name'] == 'Trump'
                              ? Colors.pink
                              : Colors.blue),
                    ),
                  );
                },
              );
            }
            return LinearProgressIndicator();
          },
        ),
      ),
    );
  }
}

Conclusion

This article covered the fundamentals and went over some examples of the StreamBuilder widget. If you would like to explore more things about Flutter, take a look at the following articles: Example of sortable DataTable in Flutter, 4 Ways to Store Data Offline in Flutter, How to implement FutureBuilder in Flutter, How to render HTML content in Flutter.

You can also check out our Flutter topic page or Dart topic page for the latest tutorials and examples.

Related Articles

guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x