@@ -13,34 +13,54 @@ void main() => runApp(const StreamBuilderExampleApp());
13
13
class StreamBuilderExampleApp extends StatelessWidget {
14
14
const StreamBuilderExampleApp ({super .key});
15
15
16
+ static const Duration delay = Duration (seconds: 1 );
17
+
16
18
@override
17
19
Widget build (BuildContext context) {
18
20
return const MaterialApp (
19
- home: StreamBuilderExample (),
21
+ home: StreamBuilderExample (delay : delay ),
20
22
);
21
23
}
22
24
}
23
25
24
26
class StreamBuilderExample extends StatefulWidget {
25
- const StreamBuilderExample ({super .key});
27
+ const StreamBuilderExample ({
28
+ required this .delay,
29
+ super .key,
30
+ });
31
+
32
+ final Duration delay;
26
33
27
34
@override
28
35
State <StreamBuilderExample > createState () => _StreamBuilderExampleState ();
29
36
}
30
37
31
38
class _StreamBuilderExampleState extends State <StreamBuilderExample > {
32
- final Stream <int > _bids = (() {
33
- late final StreamController <int > controller;
34
- controller = StreamController <int >(
35
- onListen: () async {
36
- await Future <void >.delayed (const Duration (seconds: 1 ));
37
- controller.add (1 );
38
- await Future <void >.delayed (const Duration (seconds: 1 ));
39
- await controller.close ();
40
- },
41
- );
42
- return controller.stream;
43
- })();
39
+ late final StreamController <int > _controller = StreamController <int >(
40
+ onListen: () async {
41
+ await Future <void >.delayed (widget.delay);
42
+
43
+ if (! _controller.isClosed) {
44
+ _controller.add (1 );
45
+ }
46
+
47
+ await Future <void >.delayed (widget.delay);
48
+
49
+ if (! _controller.isClosed) {
50
+ _controller.close ();
51
+ }
52
+ },
53
+ );
54
+
55
+ Stream <int > get _bids => _controller.stream;
56
+
57
+ @override
58
+ void dispose () {
59
+ if (! _controller.isClosed) {
60
+ _controller.close ();
61
+ }
62
+ super .dispose ();
63
+ }
44
64
45
65
@override
46
66
Widget build (BuildContext context) {
@@ -50,86 +70,108 @@ class _StreamBuilderExampleState extends State<StreamBuilderExample> {
50
70
child: Container (
51
71
alignment: FractionalOffset .center,
52
72
color: Colors .white,
53
- child: StreamBuilder <int >(
54
- stream: _bids,
55
- builder: (BuildContext context, AsyncSnapshot <int > snapshot) {
56
- List <Widget > children;
57
- if (snapshot.hasError) {
73
+ child: BidsStatus (bids: _bids),
74
+ ),
75
+ );
76
+ }
77
+ }
78
+
79
+ class BidsStatus extends StatelessWidget {
80
+ const BidsStatus ({
81
+ required this .bids,
82
+ super .key,
83
+ });
84
+
85
+ final Stream <int >? bids;
86
+
87
+ @override
88
+ Widget build (BuildContext context) {
89
+ return StreamBuilder <int >(
90
+ stream: bids,
91
+ builder: (BuildContext context, AsyncSnapshot <int > snapshot) {
92
+ List <Widget > children;
93
+ if (snapshot.hasError) {
94
+ children = < Widget > [
95
+ const Icon (
96
+ Icons .error_outline,
97
+ color: Colors .red,
98
+ size: 60 ,
99
+ ),
100
+ Padding (
101
+ padding: const EdgeInsets .only (top: 16 ),
102
+ child: Text ('Error: ${snapshot .error }' ),
103
+ ),
104
+ Padding (
105
+ padding: const EdgeInsets .only (top: 8 ),
106
+ child: Text (
107
+ 'Stack trace: ${snapshot .stackTrace }' ,
108
+ maxLines: 1 ,
109
+ overflow: TextOverflow .ellipsis,
110
+ ),
111
+ ),
112
+ ];
113
+ } else {
114
+ switch (snapshot.connectionState) {
115
+ case ConnectionState .none:
116
+ children = const < Widget > [
117
+ Icon (
118
+ Icons .info,
119
+ color: Colors .blue,
120
+ size: 60 ,
121
+ ),
122
+ Padding (
123
+ padding: EdgeInsets .only (top: 16 ),
124
+ child: Text ('Select a lot' ),
125
+ ),
126
+ ];
127
+ case ConnectionState .waiting:
128
+ children = const < Widget > [
129
+ SizedBox (
130
+ width: 60 ,
131
+ height: 60 ,
132
+ child: CircularProgressIndicator (),
133
+ ),
134
+ Padding (
135
+ padding: EdgeInsets .only (top: 16 ),
136
+ child: Text ('Awaiting bids...' ),
137
+ ),
138
+ ];
139
+ case ConnectionState .active:
58
140
children = < Widget > [
59
141
const Icon (
60
- Icons .error_outline ,
61
- color: Colors .red ,
142
+ Icons .check_circle_outline ,
143
+ color: Colors .green ,
62
144
size: 60 ,
63
145
),
64
146
Padding (
65
147
padding: const EdgeInsets .only (top: 16 ),
66
- child: Text ('Error: ${snapshot .error }' ),
148
+ child: Text ('\$ ${snapshot .data }' ),
149
+ ),
150
+ ];
151
+ case ConnectionState .done:
152
+ children = < Widget > [
153
+ const Icon (
154
+ Icons .info,
155
+ color: Colors .blue,
156
+ size: 60 ,
67
157
),
68
158
Padding (
69
- padding: const EdgeInsets .only (top: 8 ),
70
- child: Text ('Stack trace: ${snapshot .stackTrace }' ),
159
+ padding: const EdgeInsets .only (top: 16 ),
160
+ child: Text (
161
+ snapshot.hasData
162
+ ? '\$ ${snapshot .data } (closed)'
163
+ : '(closed)' ,
164
+ ),
71
165
),
72
166
];
73
- } else {
74
- switch (snapshot.connectionState) {
75
- case ConnectionState .none:
76
- children = const < Widget > [
77
- Icon (
78
- Icons .info,
79
- color: Colors .blue,
80
- size: 60 ,
81
- ),
82
- Padding (
83
- padding: EdgeInsets .only (top: 16 ),
84
- child: Text ('Select a lot' ),
85
- ),
86
- ];
87
- case ConnectionState .waiting:
88
- children = const < Widget > [
89
- SizedBox (
90
- width: 60 ,
91
- height: 60 ,
92
- child: CircularProgressIndicator (),
93
- ),
94
- Padding (
95
- padding: EdgeInsets .only (top: 16 ),
96
- child: Text ('Awaiting bids...' ),
97
- ),
98
- ];
99
- case ConnectionState .active:
100
- children = < Widget > [
101
- const Icon (
102
- Icons .check_circle_outline,
103
- color: Colors .green,
104
- size: 60 ,
105
- ),
106
- Padding (
107
- padding: const EdgeInsets .only (top: 16 ),
108
- child: Text ('\$ ${snapshot .data }' ),
109
- ),
110
- ];
111
- case ConnectionState .done:
112
- children = < Widget > [
113
- const Icon (
114
- Icons .info,
115
- color: Colors .blue,
116
- size: 60 ,
117
- ),
118
- Padding (
119
- padding: const EdgeInsets .only (top: 16 ),
120
- child: Text ('\$ ${snapshot .data } (closed)' ),
121
- ),
122
- ];
123
- }
124
- }
125
-
126
- return Column (
127
- mainAxisAlignment: MainAxisAlignment .center,
128
- children: children,
129
- );
130
- },
131
- ),
132
- ),
167
+ }
168
+ }
169
+
170
+ return Column (
171
+ mainAxisAlignment: MainAxisAlignment .center,
172
+ children: children,
173
+ );
174
+ },
133
175
);
134
176
}
135
177
}
0 commit comments