original
https://medium.com/flutterdevs/exploring-streambuilder-in-flutter-5958381bca67
text
Asynchronous interaction may require an ideal opportunity to summarize. Occasionally, some values may be issued before the end of the period. In Dart, you can create a capacity that returns a Stream, which can emit some value while the asynchronous process is active. Suppose you need to construct a widget in Flutter based on a snapshot of a Stream, then there is a widget called StreamBuilder.
In this blog, we will explore StreamBuilder in Flutter. We will also implement a demo program and show you how to use StreamBuilder in your Flutter application.
introduce:
StreamBuilder can listen to the public stream, and return widgets and capture a snapshot of the obtained stream information. The stream maker put forward two arguments.
A stream
Builder, which can change multiple components in the stream into widgets
Stream is like a line. When you enter a value from one end and a listener from the other end, the listener will get that value. A stream can have multiple listeners, and the load of these listeners can get the pipeline, and the pipeline will get the same value. How to place values on the stream is achieved by using a stream controller. The flow builder is a widget that can change user-defined objects into flows.
builder:
To use StreamBuilder, you need to call the following constructor:
const StreamBuilder({
Key? key,
Stream<T>? stream,
T? initialData,
required AsyncWidgetBuilder<T> builder,
})
In fact, you need to create a Stream and pass it as a stream contention. Then, at this point, you need to pass an AsyncWidgetBuilder, which can be used to construct widgets that rely on Stream snapshots.
parameter:
Here are some parameters of StreamBuilderare:
Key? key
: The widget key, used to control how the widget is replaced by another widgetStream<T>? stream
: A stream whose snapshot can be obtained through the generator functionT? initialData
: This data will be used to make an initial snapshotrequired AsyncWidgetBuilder<T> builder
: The generation process is used by this generator
How to implement the code in the dart file:
You need to implement it in your code separately:
Let's create a stream:
The following function returns a Stream that generates one number per second. You need to use the async * keyword to create a stream. To emit a value, you can use the yield keyword followed by the value to be emitted.
Stream<int> generateNumbers = (() async* {
await Future<void>.delayed(Duration(seconds: 2));
for (int i = 1; i <= 10; i++) {
await Future<void>.delayed(Duration(seconds: 1));
yield i;
}
})();
From that point onward, pass it as the stream argument
From that point on, pass it as a stream parameter
StreamBuilder<int>(
stream: generateNumbers,
// other arguments
)
Let's create an AsyncWidgetBuilder
The constructor expects you to pass a naming contention builder of type AsyncWidgetBuilder. This is a function with two parameters, their types are BuildContext and AsyncSnapshot \< t>. Subsequent boundaries (including the current snapshot) can be used to determine what should be presented.
To create this function, you first need to understand AsyncSnapshot. AsyncSnapshot is an unchanging description of the latest communication using asynchronous computing. In this unique situation, it solves the latest communication with Stream. The latest snapshot of the stream can be obtained through the AsyncSnapshot property. One of the attributes you may need to use is connectionState. This enumeration converts the current associated state to asynchronous calculation. In this special case, this asynchronous calculation is Steam.
StreamBuilder<int>(
stream: generateNumbers,
builder: (
BuildContext context,
AsyncSnapshot<int> snapshot,
) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.connectionState == ConnectionState.active
|| snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return const Text('Error');
} else if (snapshot.hasData) {
return Text(
snapshot.data.toString(),
style: const TextStyle(color: Colors._red_, fontSize: 40)
);
} else {
return const Text('Empty data');
}
} else {
return Text('State: ${snapshot.connectionState}');
}
},
),
AsyncSnapshot also has a property called hasError, which can be used to check whether the snapshot contains a non-empty error value. If the latest result of the asynchronous activity fails, the hasError value will be valid. In order to obtain information, first, you can check whether the snapshot contains information by obtaining its hasData property. If the Stream effectively releases any non-null values, then the hasData property will be valid. Then, at this point, you can get information from the data attributes of AsyncSnapshot.
Because of the values of the above attributes, you can calculate what should be displayed on the screen. In the code below, when the connectionState value is waiting, a CircularProgressIndicator will be displayed. When connectionState is changed to active or done, you can check the snapshot for errors or information. The construction function is called Flutter pipeline inspection. Therefore, it will get a subgroup of snapshots related to time. This means that if the Stream emits some values at actually similar times, some of the values may not be passed to the builder.
Enumerations have some possible values:
- \> none: None: Not associated with any asynchronous calculation. If the stream is empty, it may happen
- \> waiting: Waiting: Associated with asynchronous calculation and waiting for collaboration. In this context, it implies that the flow is not yet complete
- \> active: active: associated with active asynchronous calculations. For example, if a Stream has returned any value, but it is not over yet
- \> done:> Done: Associated with the completed asynchronous calculation. In this context, it implies that the flow has been completed
Set initial data:
You can choose to pass a worth as the initialData parameter, this parameter will be used until Stream sends out a. If the passed value is not empty, then when the connectionState is waiting, the hasData property will first be true in any event
StreamBuilder<int>(
initialData: 0,
// other arguments
)
To display the initial data while the connectionState is waiting, you should adjust if snapshot.connectionState == connectionState.waiting, and then adjust the block in the code above.
if (snapshot.connectionState == ConnectionState.waiting) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
Visibility(
visible: snapshot.hasData,
child: Text(
snapshot.data.toString(),
style: const TextStyle(color: Colors._black_, fontSize: 24),
),
),
],
);
}
When we run the application, we should get the screen output like the screen video below.
Code File:
Password file:
import 'package:flutter/material.dart';
import 'package:flutter_steambuilder_demo/splash_screen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Splash(),
debugShowCheckedModeBanner: false,
);
}
}
Stream<int> generateNumbers = (() async* {
await Future<void>.delayed(Duration(seconds: 2));
for (int i = 1; i <= 10; i++) {
await Future<void>.delayed(Duration(seconds: 1));
yield i;
}
})();
class StreamBuilderDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _StreamBuilderDemoState ();
}
}
class _StreamBuilderDemoState extends State<StreamBuilderDemo> {
@override
initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: const Text('Flutter StreamBuilder Demo'),
),
body: SizedBox(
width: double._infinity_,
child: Center(
child: StreamBuilder<int>(
stream: generateNumbers,
initialData: 0,
builder: (
BuildContext context,
AsyncSnapshot<int> snapshot,
) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
Visibility(
visible: snapshot.hasData,
child: Text(
snapshot.data.toString(),
style: const TextStyle(color: Colors._black_, fontSize: 24),
),
),
],
);
} else if (snapshot.connectionState == ConnectionState.active
|| snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return const Text('Error');
} else if (snapshot.hasData) {
return Text(
snapshot.data.toString(),
style: const TextStyle(color: Colors._red_, fontSize: 40)
);
} else {
return const Text('Empty data');
}
} else {
return Text('State: ${snapshot.connectionState}');
}
},
),
),
),
);
}
}
Conclusion:
In this article, I have briefly introduced the basic structure of StreamBuilder; you can modify this code according to your choice. This is my little introduction to StreamBuilder On User Interaction, which is working with Flutter.
© Cat brother
- https://ducafecat.tech/
- https://github.com/ducafecat
- WeChat group ducafecat
- b Station https://space.bilibili.com/404904528
Past
Open source
GetX Quick Start
https://github.com/ducafecat/getx_quick_start
News client
https://github.com/ducafecat/flutter_learn_news
strapi manual translation
WeChat discussion group ducafecat
Series collection
Translation
https://ducafecat.tech/categories/%E8%AF%91%E6%96%87/
Open source project
https://ducafecat.tech/categories/%E5%BC%80%E6%BA%90/
Dart programming language basics
https://space.bilibili.com/404904528/channel/detail?cid=111585
Getting started with Flutter zero foundation
https://space.bilibili.com/404904528/channel/detail?cid=123470
Flutter actual combat from scratch news client
https://space.bilibili.com/404904528/channel/detail?cid=106755
Flutter component development
https://space.bilibili.com/404904528/channel/detail?cid=144262
Flutter Bloc
https://space.bilibili.com/404904528/channel/detail?cid=177519
Flutter Getx4
https://space.bilibili.com/404904528/channel/detail?cid=177514
Docker Yapi
https://space.bilibili.com/404904528/channel/detail?cid=130578
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。