Maybe the easiest way to handle user input during async operations is to simply block the entire UI. Sure, there are friendlier ways but if we don’t block the UI we may need to handle cancels and late-response errors in a much more complicated manner. Simply showing a modal progress like below is an efficient and not too horrible method.

I tried this first using a FutureBuilder and keeping a variable for when I was loading or not. Having another layer being rendered caused my widget tree to re-render though and form data to be lost. It also added a lot more complexity to the screen that simply didn’t feel like it belonged there.

I came across an answer from Stackoverflow using a dialog. This turned out a real clean and small solution. I even wrapped this in some helper functions leading my final usage to look like this:

final overlay = LoadingOverlay.of(context);
final result = await overlay.during(widget.authentication.signUp(email, password));

The overlay code is also small enough to easily copy/paste into your project:

Two things worry me though:

  1. Popping the navigator like this without being 100% sure we’re popping it from a valid state.
  2. Keeping the context as a variable in order to close after finishing. The context is very much alive and I’ve had all sorts of issues with keeping it as a member as opposed to passing it in.

However, with a bit more tweaking we could make that a bit prettier/safer and all-in-all this solution works swell from what I can see. I really like the way it’s wrappable in a way that the execution of the future doesn’t need to care about the rendering.

How do you solve overlays for progress? Any tips?