StreamBuilder是否总是被调用两次?一次用于初始数据,然后一次用于输入流?
初始化以下StreamBuilder表示,两次调用了build方法。第二个电话比第一个电话晚0.4秒。
流:内部版本1566239814897
流:内部版本1566239815284
import 'dart:async';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:nocd/utils/bloc_provider.dart';
void main() =>
runApp(BlocProvider<MyAppBloc>(bloc: MyAppBloc(), child: MyApp()));
class MyAppBloc extends BlocBase {
String _page = window.defaultRouteName ?? "";
/// Stream for [getPage].
StreamController<String> pageController = StreamController<String>();
/// Observable navigation route value.
Stream get getPage => pageController.stream;
MyAppBloc() {}
@override
void dispose() {
pageController.close();
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final MyAppBloc myAppBloc = BlocProvider.of<MyAppBloc>(context);
return StreamBuilder(
stream: myAppBloc.getPage,
initialData: "Build",
builder: (context, snapshot) {
print("Stream: " +
snapshot.data +
DateTime.now().millisecondsSinceEpoch.toString());
return Container();
},
);
}
}
为什么StreamBuilder被调用两次?
答案 0 :(得分:0)
StreamBuilder在初始化时进行两次构建调用,一次用于初始数据,第二次用于流数据。
流不保证它们将立即发送数据,因此需要初始数据值。将null
传递到initialData
会引发InvalidArgument异常。
即使传递的流为null,StreamBuilders也会始终生成两次。
答案 1 :(得分:0)
Streambuilder将被调用2次,第一次是Initial,第二次是Stream。并且仅在状态为 ConnectionState.active”时更改数据。 请参阅官方文档示例。
StreamBuilder<int>(
//stream:fire, // a Stream<int> or null
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
if (snapshot.hasError) return Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('Select lot');
case ConnectionState.waiting:
return Text('Awaiting bids...');
case ConnectionState.active:
return Text('\$${snapshot.data}');
case ConnectionState.done:
return Text('\$${snapshot.data} (closed)');
}
return null; // unreachable
},
);
可以通过指定initialData来控制初始快照数据。应该使用此方法来确保第一帧具有期望的值,因为将始终在流侦听器有机会被处理之前调用生成器。
提供此值(大概在创建Stream时以某种方式同步获得)可确保第一帧显示有用的数据。否则,无论流上是否有可用值,都将使用零值构建第一帧:由于流是异步的,因此在初始构建之前无法从流中获取任何事件。