This article walks you through a complete example of using Stream.periodic in Flutter.
Table of Contents
Overview
The Stream.periodic constructor, as its name implies, is used to create a stream that broadcasts events repeatedly at period intervals:
Stream<dynamic> Stream.periodic(
Duration period,
[dynamic Function(int)? computation]
)
Note:
- The period parameter must be a non-negative Duration.
- If the computation function is omitted, the event values will all be null.
- The computation function must not be omitted if the event type T does not allow null as a value
Sample usage:
final Stream _myStream =
Stream.periodic(const Duration(seconds: 1), (int count) {
print(DateTime.now());
});
If you feel words are too boring and confusing and just like to dive into the code then move on to the example below.
The Example
Preview
The app we are going to build has a background color that changes over time. It also displays an increasing number in the center of the screen. We can stop these relentless behaviors by pressing the floating button.
Here’s how it works:
The Code
The full source code in main.dart with explanations:
// main.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:math';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// Hide the debug banner
debugShowCheckedModeBanner: false,
title: 'KindaCode.com',
theme: ThemeData(
primarySwatch: Colors.indigo,
),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final Stream _myStream =
Stream.periodic(const Duration(seconds: 1), (int count) {
return count;
});
// The subscription on events from _myStream
late StreamSubscription _sub;
// This number will be displayed in the center of the screen
// It changes over time
int _computationCount = 0;
// Background color
// In the beginning, it's indigo but it will be a random color later
Color _bgColor = Colors.indigo;
@override
void initState() {
_sub = _myStream.listen((event) {
setState(() {
_computationCount = event;
// Set the background color to a random color
_bgColor = Colors.primaries[Random().nextInt(Colors.primaries.length)];
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: _bgColor,
appBar: AppBar(
title: const Text('KindaCode.com'),
backgroundColor: Colors.transparent,
),
body: Center(
child: Text(
_computationCount.toString(),
style: const TextStyle(fontSize: 150, color: Colors.white),
),
),
// This button is used to unsubscribe the stream listener
floatingActionButton: FloatingActionButton(
child: const Icon(
Icons.stop,
size: 30,
),
onPressed: () => _sub.cancel(),
),
);
}
// Cancel the stream listener on dispose
@override
void dispose() {
_sub.cancel();
super.dispose();
}
}
Conclusion
We’ve examined a practical example of implementing Stream.periodic in Flutter. If you’d like to learn more about stream, similar things to stream, and other stuff in Flutter, take a look at the following articles:
- Flutter StreamBuilder examples (null safety)
- Working with Timer and Timer.periodic in Flutter
- Flutter + Firebase Storage: Upload, Retrieve, and Delete files
- Flutter and Firestore Database: CRUD example (null safety)
- 2 Ways to Create Flipping Card Animation in Flutter
- Flutter: Caching Network Images for Big Performance gains
You can also take a tour around our Flutter topic page and Dart topic page to see the latest tutorials and examples.