Flutter StreamBuilder未按预期从流中读取数据
我试图使用StreamBuilder从流中读取一些数据,但snapshot.data仅返回流中的最后一项。在这种情况下,我只得到“f”。我想得到‘a’、‘b’、‘c’、‘d’、‘e’、‘f’。我做错了什么Flutter StreamBuilder未按预期从流中读取数据,flutter,dart,Flutter,Dart,我试图使用StreamBuilder从流中读取一些数据,但snapshot.data仅返回流中的最后一项。在这种情况下,我只得到“f”。我想得到‘a’、‘b’、‘c’、‘d’、‘e’、‘f’。我做错了什么 class ProgressWidget extends StatefulWidget { //ProgressWidget({this.stream}) : super(); //final Stream<String> stream; @override _P
class ProgressWidget extends StatefulWidget {
//ProgressWidget({this.stream}) : super();
//final Stream<String> stream;
@override
_ProgressWidgetState createState() => _ProgressWidgetState();
}
class _ProgressWidgetState extends State<ProgressWidget> {
int _progressCount = 0;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Stream.fromIterable(['a', 'b', 'c', 'd', 'e', 'f']), // test stream
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
_progressCount++;
if (snapshot.hasData) {
print(snapshot.data);
}
return snapshot.hasData
? new Text('Progress $_progressCount ' + snapshot.data)
: new Text('Loading ... ');
});
}
}
class ProgressWidget扩展了StatefulWidget{
//ProgressWidget({this.stream}):super();
//最终河流;
@凌驾
_ProgressWidgetState createState()=>\u ProgressWidgetState();
}
类_ProgressWidgetState扩展状态{
int _progressCount=0;
@凌驾
void initState(){
super.initState();
}
@凌驾
小部件构建(构建上下文){
返回流生成器(
stream:stream.fromIterable(['a','b','c','d','e','f']),//测试流
生成器:(BuildContext上下文,异步快照){
_progressCount++;
if(snapshot.hasData){
打印(快照数据);
}
返回snapshot.hasData
?新文本('Progress$\u progressCount'+snapshot.data)
:新文本('加载…');
});
}
}
试试这个:
class _ProgressWidgetState extends State<ProgressWidget> {
int _progressCount = 0;
Stream<String> _stream;
List<String> _source = ['a', 'b', 'c', 'd', 'e', 'f'];
@override
void initState() {
super.initState();
_stream = Stream.periodic(Duration(seconds: 1), (i) => _source[i]).take(_source.length);
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: _stream, // test stream
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
_progressCount++;
return snapshot.hasData ? new Text('Progress $_progressCount ' + snapshot.data) : new Text('Loading ... ');
},
);
}
}
class\u ProgressWidgetState扩展状态{
int _progressCount=0;
溪流;;
列表_source=['a','b','c','d','e','f'];
@凌驾
void initState(){
super.initState();
_stream=stream.periodic(持续时间(秒:1),(i)=>_source[i])。取(_source.length);
}
@凌驾
小部件构建(构建上下文){
返回流生成器(
流:\ u流,//测试流
生成器:(BuildContext上下文,异步快照){
_progressCount++;
返回snapshot.hasData?新文本('Progress$\u progressCount'+snapshot.data):新文本('Loading…');
},
);
}
}
像这样创建流:
Stream<String> listStream(Duration interval, List<String> list) async* {
int i = 0;
while (i<list.length) {
await Future.delayed(interval);
yield list[i];
i++;
}
}
Stream listStream(持续时间间隔,列表)异步*{
int i=0;
而(i_ProgressWidgetState();
}
类_ProgressWidgetState扩展状态{
int _progressCount=0;
字符串str='';
@凌驾
void initState(){
super.initState();
}
Stream listStream(持续时间间隔,列表列表)异步*{
int i=0;
while(这与您前面的问题相同:在引擎盖下StreamBuilder
是一个StatefulWidget
,它在同一个框架中调用多个setState()
(或者可能试图更聪明,在不需要时跳过调用):您无法避免它,但现在您的代码比使用await\u stream.forEach((行)要简单得多
以及诸如此类的事情为什么你坚持要在流中的每个项目上重建你的小部件?请记住,setState
是与60Hz同步的,所以…显示所有内容会非常慢…对不起,我是新来的flifter,仍在学习,第一段说:“小部件重建由每个交互使用State.setState进行计划,但在其他方面与流的计时分离。由颤振管道自行决定调用生成器,因此将接收表示与流交互的快照的计时相关子序列。"但是,即使你的StreamBuilder
没有显示你的所有数据,这并不意味着某些数据没有从你的流中读取-这根本不显示。这是可行的,谢谢,但我必须弄清楚如何读取一个大文件,并每隔一定数量的行显示进度。你可能想检查一下Dio客户端,我看到它有一个程序ress回调,我想它可以用来监控下载了多少字节
class ProgressWidget extends StatefulWidget {
//ProgressWidget({this.stream}) : super();
//final Stream<String> stream;
@override
_ProgressWidgetState createState() => _ProgressWidgetState();
}
class _ProgressWidgetState extends State<ProgressWidget> {
int _progressCount = 0;
String str = '';
@override
void initState() {
super.initState();
}
Stream<String> listStream(Duration interval, List<String> list) async* {
int i = 0;
while (i<list.length) {
await Future.delayed(interval);
yield list[i];
i++;
}
}
@override
Widget build(BuildContext context) {
return StreamBuilder<String>(
stream:listStream(Duration(milliseconds:300), ['a', 'b', 'c', 'd', 'e', 'f']),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
_progressCount++;
if (snapshot.hasData) {
print(snapshot.data);
str += snapshot.data;
}
return snapshot.hasData
? new Text('Progress $_progressCount ' + str)
: new Text('Loading ... ');
});
}
}