- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个包装在另一个StreamBuilder中的StreamBuilder。内部StreamBuilder会将来自分页的异步查询的结果加载到ListView中。外部StreamBuilder会使用用户指定的搜索文本发出新查询,并构建新的内部StreamBuilder来侦听新查询。该查询使用生成器函数生成流。
我注意到一些非常奇怪的行为:
发出新查询并用新Stream重建内部StreamBuilder时,它最初会从先前的Stream接收数据。当新的Stream为空时(例如,用户的查询未产生结果),这一点尤其明显。如果新的Stream为空,则它从ConnectionState.waiting
变为ConnectionState.done
,并且两个事件(我认为是错误的)都填充有前一个生成器Stream的数据。
这是我编写的一些代码,它们以尽可能孤立的方式重现此代码。为了简单起见,我将外部StreamBuilder替换为FutureBuilder,尽管其行为是相同的。
import 'dart:async';
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final Future<bool> oneSecondFuture = Future.delayed(Duration(seconds: 2), () {
print('future completed!');
return true;
});
@override
Widget build(BuildContext context) {
Stream<int> intStream(bool returnValues) async* {
var lst = [1, 2, 3];
var i = 0;
while (returnValues) {
if (i == lst.length) break;
yield lst[i++];
await Future.delayed(Duration(milliseconds: 40));
}
}
print('building');
var futureBuilder = FutureBuilder(
future: oneSecondFuture,
builder: (_, boolSnap) {
// If the future isn't complete yet, return a StreamBuilder with a nonempty stream
if (!boolSnap.hasData) return StreamBuilder(
stream: intStream(true),
builder: (_, intSnap) {
print('Nonempty steambuilder: ' + intSnap.connectionState.toString() + '; ' + intSnap.data.toString());
return Text(intSnap.data.toString());
}
);
// If the future is complete, return a StreamBuilder with an empty stream
return StreamBuilder(
stream: intStream(false),
builder: (_, intSnap) {
print('Empty steambuilder: ' + intSnap.connectionState.toString() + '; ' + intSnap.data.toString());
return Text(intSnap.data.toString());
}
);
}
);
return MaterialApp(
title: 'Test StreamBuilder',
home: futureBuilder,
);
}
}
上面的代码产生以下打印输出:
I/flutter (20225): building
I/flutter (20225): Nonempty streambuilder: ConnectionState.waiting; null
I/flutter (20225): Nonempty streambuilder: ConnectionState.active; 1
I/flutter (20225): Nonempty streambuilder: ConnectionState.active; 2
I/flutter (20225): Nonempty streambuilder: ConnectionState.active; 3
I/flutter (20225): Nonempty streambuilder: ConnectionState.done; 3
I/flutter (20225): building
I/flutter (20225): Nonempty streambuilder: ConnectionState.waiting; 3
I/flutter (20225): Nonempty streambuilder: ConnectionState.active; 1
I/flutter (20225): Nonempty streambuilder: ConnectionState.active; 2
I/flutter (20225): Nonempty streambuilder: ConnectionState.active; 3
I/flutter (20225): Nonempty streambuilder: ConnectionState.done; 3
I/flutter (20225): future completed!
I/flutter (20225): Empty streambuilder: ConnectionState.waiting; 3
I/flutter (20225): Empty streambuilder: ConnectionState.done; 3
请注意,在等待连接时,第二个构建以最后一个流的值“3”开始。空流对于等待事件和完成事件均产生值为3的值。
I/flutter (20225): building
I/flutter (20225): Nonempty streambuilder: ConnectionState.waiting; null
I/flutter (20225): Nonempty streambuilder: ConnectionState.active; 1
I/flutter (20225): Nonempty streambuilder: ConnectionState.active; 2
I/flutter (20225): Nonempty streambuilder: ConnectionState.active; 3
I/flutter (20225): Nonempty streambuilder: ConnectionState.done; 3
I/flutter (20225): building
I/flutter (20225): Nonempty streambuilder: ConnectionState.waiting; 3
I/flutter (20225): Nonempty streambuilder: ConnectionState.active; 1
I/flutter (20225): Nonempty streambuilder: ConnectionState.active; 2
I/flutter (20225): Nonempty streambuilder: ConnectionState.active; 3
I/flutter (20225): Nonempty streambuilder: ConnectionState.done; 3
I/flutter (20225): future completed!
I/flutter (20225): using a different generator function:
I/flutter (20225): Empty streambuilder: ConnectionState.waiting; null
I/flutter (20225): Empty streambuilder: ConnectionState.done; null
这是预期的行为吗?有没有一种让我可以让StreamBuilder不接收来自先前生成器Stream的数据的明智方法?我想我可以创建两个相同的生成器函数并在它们之间交替,但是我真的很想在这里找到一个不太麻烦的解决方案。
最佳答案
我已经通过仔细阅读文档回答了自己的问题。这似乎是(令人难以置信的)预期行为。参见documentation。
但是,我仍然不清楚为什么使用来自相同生成器函数的新流将触发此行为,而使用来自不同生成器函数的新流却不会触发此行为。
无论哪种方式,对于任何其他面临相同问题的人,我打算解决的方法是在ConnectionState为“waiting”或“done”时忽略错误的数据值,只要流为空(例如,“done”快照)却没有收到有效的事件值)。
关于flutter - Flutter StreamBuilder从先前的生成器流中生成快照,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64518456/
我是一名优秀的程序员,十分优秀!