when i try to use CircularProgressIndicator with slow async method, indicator is not shown. When i replace slow custom method with Timer.pereodic() that works fine. I am new in Flutter and do not understand what i am doing wrong
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.
In the first place, there is no
await
keyword in the_slowMethod
, and that technically means you need to wrap the "what-should-be-asynchronous" operation in aFuture
andawait
for it.So what should be your solution is something like the following for the
_slowMethod()
:But then as Richard Heap (@Richard Heap) pointed in the comments, the above would have issues working. If you run the code, the
CircularProgressIndicator
will have problems displaying because the main Dart thread has been hijacked by the demanding fibonacci sequence and your UI won't render properly.I'm supposing that you really might not have a Fibonacci of up to 100 in production code. That probably, you used it to show us the problem. But even if it is the case or you have complex asynchronous operations, you could use Isolates as Richard mentioned.
If the asynchronous operation is not very demanding on the main thread, (like simply doing
Future.delayed
), awaiting the future should work.The following snippet will behave as you expect.