logo
icon_menu
  1. Home
  2. Categories
  3. Flutter

Tutorial: Simple Flutter app initialization with Splash Screen using FutureBuilder

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 setup 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

name: initialization description: Initialization with Splash Screen version: 1.0.0+1 environment: sdk: ">=2.1.0 <3.0.0" dependencies: flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter
Code language: YAML (yaml)

main.dart

import 'package:flutter/material.dart'; void main() => runApp(InitializationApp()); class InitializationApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Initialization', home: HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Initialization"), ), ); } }
Code language: Dart (dart)
Flutter Initialization Home Page
When you start the app you should see something like this.

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

class Init { static Future initialize() async { await _registerServices(); await _loadSettings(); } static _registerServices() async { //TODO register services } static _loadSettings() async { //TODO load settings } }
Code language: Dart (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:

static _registerServices() async { print("starting registering services"); await Future.delayed(Duration(seconds: 1)); print("finished registering services"); } static _loadSettings() async { print("starting loading settings"); await Future.delayed(Duration(seconds: 1)); print("finished loading settings"); }
Code language: Dart (dart)

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

import 'package:flutter/material.dart'; class SplashScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Material( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( "Initialization", style: TextStyle( fontSize: 32, fontWeight: FontWeight.bold, ), ), SizedBox(height: 20), CircularProgressIndicator() ], ), ); } }
Code language: Dart (dart)

Let’s go through the lines in this file in more detail.

  • Line 3: SplashScreen extends StatelessWidget. We do not need to handle any state in this widget, only show a static splash screen page, so StatelessWidget is best suited for our purpose.
  • Line 6: We wrap everything in a Material widget. This makes sure that the default text style is properly set.
  • Line 7 & 8: To organize the Text and the CircularProgressIndicator we use the Column Widget. To center the children of the Column vertically we set the mainAxisAlignment to MainAxisAlignment.center.
  • Line 10 – 18: Add a Text with some custom style. To make sure there is a bit of space between the Text and the CircularProgressIndicator we add a SizedBox with 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.

Flutter Initialization Splash Screen
This is how our splash screen should look like while we initialize our app.

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

... class InitializationApp extends StatelessWidget { final Future _initFuture = Init.initialize(); @override Widget build(BuildContext context) { return MaterialApp( title: 'Initialization', home: FutureBuilder( future: _initFuture, builder: (context, snapshot){ if (snapshot.connectionState == ConnectionState.done){ return HomePage(); } else { return SplashScreen(); } }, ), ); } } ...
Code language: Dart (dart)

Let’s see what we did here:

  • Line 5: Here we call our initialize function. Since it’s an async function it will run in the background and won’t stop the rest of the app from executing. The Future returned by initialize is stored in a private variable (note the _ ) so we can use it with the FutureBuilder below.
  • Lines 11 & 12: Instead of directly assigning HomePage to the home attribute of our MaterialApp, we’ll put a FutureBuilder here. This widget will observe the Future provided by the future attribute and will rebuild once the state of the Future changes.
  • Lines 13 – 19: The builder attribute allows us to specify which widget should be displayed depending on our future’s state. As all builder functions in Flutter it provides a BuildContext. But what is more interesting here is the snapshot parameter. This parameter allows us to have a look at the state of our Future. To see whether it has completed running we will check its connectionState. The state that is the most interesting to us is ConnectionState.done. This state tells us that the Future has completed executing and the initialization has finished: time to display our HomePage. In any other cases we will display our SplashScreen.

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 statup shows what part of the initialization has ben executed. So if everything is initialized the conosle should display something like:

flutter: starting registering services flutter: finished registering services flutter: starting loading settings flutter: finished loading settings
Code language: HTTP (http)

It might also make sense to handle errors that can occur during your initalization 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 a initialization function that is able to run asynchroniously and have a FutureBuilder reacting to the state of your initialization code.

If you have any recommendations or remarks on how to best handle your app startup leave a comment below!

Comments

Felix says:

Thanks a lot for the tutorial, was very helpful!

Monish Sinthala says:

Thanks a lot, buddy! The tutorial was very good. Very useful and helpful for flutter app development company employees. Will share it with my peers and friends. Kudos.

Mohamed says:

Thank you so much Dude!
Youre tuto is Great

Stefan says:

I’m happy you like it 🙂

hdk says:

i’m curious about that. thanks to your lovely simple code

MB says:

very simple and applicable, straight to the point. Then it is up to readers to investigate deeper for details by their own… really nice approach.
Thanks for it.

Leave a Reply

Your email address will not be published. Required fields are marked *