当我尝试使用CircularProgressIndicator慢异步方法时,未显示指标。当我用timer . periodic()代替缓慢的自定义方法时,效果很好。我是新的扑动和不明白我做错了什么
class _MyHomePageState extends State<MyHomePage> {
bool _inProgress = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
width: 200,
height: 200,
child: Column(
children: [
_inProgress ? CircularProgressIndicator() : Text("ready"),
FloatingActionButton(onPressed: _slowMethod)
],
),
),
),
);
}
int fibonacci(int n) {
return n <= 2 ? 1 : fibonacci(n - 2) + fibonacci(n - 1);
}
_slowMethod() async {
setState(() {
_inProgress = true;
});
for (int i = 20; i <= 100; ++i) {
print(fibonacci(i));
}
setState(() {
_inProgress = false;
});
}
}
异步函数同步运行,直到第一个await关键字出现。
首先,在_slowMethod
中没有await
关键字,这在技术上意味着您需要包装"应该是异步的";在Future
和await
中操作
那么你的解决方案应该是下面的_slowMethod()
:
_slowMethod() async {
setState(() {
_inProgress = true;
});
await Future(() {
for (int i = 20; i <= 100; ++i) {
print(fibonacci(i));
}
});
setState(() {
_inProgress = false;
});
}
但是,正如Richard Heap (@Richard Heap)在评论中指出的那样,上述操作可能会出现问题。如果你运行代码,CircularProgressIndicator
将有问题显示,因为主Dart线程已经被要求的斐波那契序列劫持,你的UI将无法正确渲染。
我假设你的产品代码中可能没有高达100的斐波那契数列。你可能用它来演示问题。但是,即使是这种情况,或者您有复杂的异步操作,您也可以使用Richard提到的isolation。
如果异步操作对主线程的要求不是很高,(比如简单地执行Future.delayed
),那么等待future应该可以工作。
下面的代码片段将按照您的期望运行。
_slowMethod() async {
setState(() {
_inProgress = true;
});
await Future.delayed(const Duration(seconds: 3));
setState(() {
_inProgress = false;
});
}