使用慢速异步方法的 Flutter 进度指示器
Flutter progress indicator with slow async method
当我尝试将 CircularProgressIndicator 与慢速异步方法一起使用时,未显示指示器。当我用 Timer.pereodic() 替换慢速自定义方法时效果很好。我是 Flutter 的新手,不明白我做错了什么
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;
});
}
}
An async function runs synchronously until the first await keyword.
首先,_slowMethod
中没有 await
关键字,从技术上讲,这意味着您需要将“what-should-be-asynchronous”操作包装在 [=14= 中] 和 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 提到的那样使用 Isolates。
如果异步操作对主线程的要求不是很高(比如简单地做Future.delayed
),等待未来应该可以。
以下代码段将按您的预期运行。
_slowMethod() async {
setState(() {
_inProgress = true;
});
await Future.delayed(const Duration(seconds: 3));
setState(() {
_inProgress = false;
});
}
当我尝试将 CircularProgressIndicator 与慢速异步方法一起使用时,未显示指示器。当我用 Timer.pereodic() 替换慢速自定义方法时效果很好。我是 Flutter 的新手,不明白我做错了什么
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;
});
}
}
An async function runs synchronously until the first await keyword.
首先,_slowMethod
中没有 await
关键字,从技术上讲,这意味着您需要将“what-should-be-asynchronous”操作包装在 [=14= 中] 和 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 提到的那样使用 Isolates。
如果异步操作对主线程的要求不是很高(比如简单地做Future.delayed
),等待未来应该可以。
以下代码段将按您的预期运行。
_slowMethod() async {
setState(() {
_inProgress = true;
});
await Future.delayed(const Duration(seconds: 3));
setState(() {
_inProgress = false;
});
}