Provides an easier to use verion of FutureBuilder.

Usage of FutureBuilderEx must use the same rules that apply to FutureBuilder:

The future must not be created during the State.build or StatelessWidget.build method call when constructing the FutureBuilder. If the future is created at the same time as the FutureBuilder, then every time the FutureBuilder's parent is rebuilt, the asynchronous task will be restarted.


The future parameter takes a function that must return a Future. We guarentee to only call the future function once.

However, if you cause the FutureBuilderEx to be recreated (e.g. you pop a page than navigate back to the page) then the future will be called once again. If you have a future that must only ever be called once then the future should be tied to your top level application widget.

Your future function may contain multiple awaits:

            future: () => selectedTeam,
            initData: "Select Team",
            waitBuilder: (context) => Text('Loading'),
            errorBuilder: (error) => Text(error),
            builder: (context, team) 
                => Text('Team: ${team.name}', color: Colors.white),


FutureBuilderEx allows you to provide three builders. The waitingBuilder and errorBuilder are optional but we recommend that you provide the waitingBuilder at the minimum unless you future always completes quickly (less than 500ms).


waitingBuilder - called whenever the render tree needs to be built and the future has not yet completed. If you don't provide a waitingBuilder then we display a default 'Loading...' textblock centered in the screen until the future completes. We only show the 'Loading...' indicator if the the future takes longer than 500ms to complete. For the first 500ms we show a empty screen as this helps to reduce flicker when the future completes quickly.


builder - called whenever the render tree needs to be built and the future has completed.


errorBuilder - called whenever the render tree needs to be built after the future returns an error.

If you don't provide an errorBuilder and the future throws an error then a generic message 'An error occured: XXXX' will be displayed.


Widget build(BuildContext contect) {
 return Consumer<SelectedTeam>(
     builder: (context, selectedTeam, _) 
       => FutureBuilderEx<SelectedTeam>(
           future: () => selectedTeam,
           waitingBuilder: (context) => Text('Select your favourite team'),
           builder: (context, teamName) 
               => Text('Selected Team: ${team.name}', color: Colors.white),
           errorBuilder: (error) => Text('Oops: $error')