Most of the apps do run some kind of initialization code when the app starts. Doing this in a **synchronous/blocking ** manner makes your app look frozen for the duration of this process. A better solution is to initialize your app in the background and show the user a splash screen in the meanwhile.
In this blog entry I’m going to give you a step-by-step guide on how to initialize your Flutter app and show a splash
screen using FutureBuilder.
Prerequisite
Before we start we will need to set up a new Flutter project. If you are new to Flutter I recommend that you follow the steps of the official tutorial first.
Use the IDE/editor of your choice to start a new Flutter project. Let’s name the project initialization. First get
rid of all the boilerplate code. I usually start my apps with pubspec.yaml and main.dart looking like this:
pubspec.yaml
| |
main.dart
| |
The Initialization Logic
Now that we have set up the basis of the app it is time to do create a place where we want to do the initialization
of our app. Therefore I will create a new file and name it init.dart. Of course I could also do the initialization
within the main.dart file, but as your app grows the number of lines in your initialization logic can get quite bulky.
init.dart
| |
The Init class contains one static public function initialize which we will later call in the main.dart file to
start the initialization.
Note the async keyword in the function declaration. Many initialization routines are built to run asynchronously. To
being able to wait for those to finish we use the await keyword. This requires our initialize function to also be in
an async context. Async functions implicitly return a Future. A Future can be seen as an object that contains
information about the state of an async function.
A more detailed guide on the async-await can be found on the official dart website.
The Init class also contains two private functions (inicated by the leading underscore): _registerServices and
_loadSettings. These are examples of how you could strucuture your initialization process in order to keep your code
easy to read.
To keep this example simple, we won’t do any real initialization here. Anyways, to simulate heavy initialilzation going
on in our app we can add a delay to our initialization functions using Future.delayed.
The two functions now should look like this:
| |
The Splash Screen
Now that we have some initialization logic for our app startup, we create a splash screen that can be displayed while
the initialization takes place. For a proper project strucuture we will create a new file and name it
splash_screen.dart.
splash_screen.dart
| |
Let’s go through the lines in this file in more detail.
Line 3:
SplashScreenextendsStatelessWidget. We do not need to handle any state in this widget, only show a static splash screen page, soStatelessWidgetis best suited for our purpose.Line 6: We wrap everything in a
Materialwidget. This makes sure that the default text style is properly set.Line 7 & 8: To organize the
Textand theCircularProgressIndicatorwe use theColumnWidget. To center the children of theColumnvertically we set themainAxisAlignmenttoMainAxisAlignment.center.Line 10 - 18: Add a
Textwith some custom style. To make sure there is a bit of space between theTextand theCircularProgressIndicatorwe add aSizedBoxwith a height of 20px between the two widgets.
And that’s it: A really simple splash screen. Of course, you can be creative here and create something more beautiful :) Leave a comment below this post with your recommendation how you think a splash screen should look like. Let’s put it all together in the next step.
Putting it together: Show the Splash Screen during Initialization
Now we move back to main.dart to wire up all the parts we have implemented before. We will use a FutureBuilder to
monitor the state of our initialization logic and show our SplashScreen while the initialization is still in progress.
main.dart
| |
Let’s see what we did here:
Line 5: Here we call our
initializefunction. Since it’s anasyncfunction it will run in the background and won’t stop the rest of the app from executing. TheFuturereturned byinitializeis stored in a private variable ( note the_) so we can use it with theFutureBuilderbelow.Lines 11 & 12: Instead of directly assigning
HomePageto thehomeattribute of our MaterialApp, we’ll put aFutureBuilderhere. This widget will observe theFutureprovided by thefutureattribute and will rebuild once the state of theFuturechanges.Lines 13 - 19: The
builderattribute allows us to specify which widget should be displayed depending on our future’s state. As all builder functions in Flutter it provides aBuildContext. But what is more interesting here is thesnapshotparameter. This parameter allows us to have a look at the state of ourFuture. To see whether it has completed running we will check itsconnectionState. The state that is the most interesting to us isConnectionState.done. This state tells us that theFuturehas completed executing and the initialization has finished: time to display ourHomePage. In any other cases we will display ourSplashScreen.
And that’s it. When you start your app now, you will see a splash screen that is displayed while the initialization takes place. A look at the console during startup shows what part of the initialization has been executed. So if everything is initialized the console should display something like:
flutter: starting registering services
flutter: finished registering services
flutter: starting loading settings
flutter: finished loading settings
It might also make sense to handle errors that can occur during your initialization process. You can use
snapshot.hasError in your build function to check if there has been an error.
Summary
Using FutureBuilder it is really simple to show a splash screen during your apps startup initialization. All you need
is an initialization function that is able to run asynchronously and have a FutureBuilder reacting to the state of
your initialization code.