我想输出进度消息,同时下载文件并在Flutter应用程序中填充数据库。
为此,我正在使用StreamBuilder和Stream,该Stream在执行工作时会生成状态消息更新。
到目前为止,一切都很好,但是现在除了状态消息外,我还要显示一些有关下载进度的详细信息。据我了解,我可以将下载进度包装在另一个流中,但是现在我对于如何从状态更新流中调用该流有些困惑。
代码现在看起来像这样:
Stream<String> _upsertResult(context) async* {
yield "Downloading Identifiers... (1/6)";
await IdentifierService.downloadIdentifiers();
yield "Upserting Identifiers... (2/6)";
await IdentifierService.upsertIdentifiers();
yield "Downloading Locations... (3/6)";
await LocationService.downloadLocations();
yield "Upserting Locations... (4/6)";
await LocationService.upsertLocations();
yield "Downloading Identifiables... (5/6)";
await IdentifiableService.downloadIdentifiables();
yield "Upserting Identifiables... (6/6)";
await IdentifiableService.upsertIdentifiables();
SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => CurtainInformationScreen()),
);
});
}
目前downloadIdentifiers()
已作为Future实现,但我可以将其重写为Stream,以便能够产生下载进度状态更新。
我想我可以听听我创建的新Stream并在_upsertResult Stream中重新产生它,但是我想知道这里是否有解决我问题的更优雅的解决方案,例如等待Stream结束,但是重新-在Stream运行时获得所有结果。
答案 0 :(得分:1)
我遵循了pskink的建议,并做到了:
yield "Downloading Identifiers... (1/6)";
yield* IdentifierService.downloadIdentifiers();
根据http://dart.goodev.org/articles/language/beyond-async#yield
yield *(发音为每个)的设计目的是为了避开 这个问题。 yield *之后的表达式必须表示另一个 (子)序列。 yield *的作用是插入 子序列到当前正在构建的序列中,就好像我们 每个元素都有自己的产量。我们可以重写代码 使用yield-each如下:
然后我可以将yield
放在downloadIdentifiers
内,值将被传递。