Ray*_* Li 6 dart flutter stream-builder
StreamBuilder 总是被调用两次吗?一次用于初始数据,然后一次用于输入流?
初始化以下 StreamBuilder 显示构建方法被调用了两次。第二个调用是在第一个调用之后的 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();
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
为什么 StreamBuilder 会被调用两次?
Streambuilder 将被调用 2 次,第一次用于 Initial,第二次用于流。并且只有在状态为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
},
);
Run Code Online (Sandbox Code Playgroud)
可以通过指定initialData 来控制初始快照数据。这应该用于确保第一帧具有预期值,因为构建器将始终在流侦听器有机会被处理之前被调用。
提供这个值(大概是在创建 Stream 时以某种方式同步获得的)确保第一帧将显示有用的数据。否则,无论流上是否有可用值,第一帧都将使用 null 值构建:由于流是异步的,因此在初始构建之前无法从流中获取任何事件。
StreamBuilder 在初始化时进行两次构建调用,一次用于初始数据,第二次用于流数据。
流不保证它们会立即发送数据,因此需要初始数据值。传递null到initialData会引发 InvalidArgument 异常。
即使传递的流为空,StreamBuilders 也将始终构建两次。
更新:
initalData在这个 Flutter 问题线程中可以找到关于为什么 StreamBuilders 多次构建多次的详细技术解释可以在这个 Flutter 问题线程中找到:https : //github.com/flutter/flutter/issues/16465
广播流不可能有初始状态。您要么在添加数据时订阅了它,要么错过了它。在异步单订阅流中,任何添加的监听调用都不会被调用,直到下一个微任务或下一个事件循环(不记得,可能取决于),但无论如何都没有办法从当前帧上的流。- 乔纳·威廉姆斯
如上所述,您只需将代码放入 Connection.Active 状态即可。见下文:
StreamBuilder<QuerySnapshot>(
stream: historicModel.query.snapshots(),
builder: (context, stream){
if (stream.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (stream.hasError) {
return Center(child: Text(stream.error.toString()));
} else if(stream.connectionState == ConnectionState.active){
//place your code here. It will prevent double data call.
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4943 次 |
| 最近记录: |