Create an Interactive Splash Screen in Flutter

muiz6

M Muiz Hassan

Posted on May 30, 2021

Create an Interactive Splash Screen in Flutter

Hi, I hope you all are doing great. In this tutorial I'll be sharing the technique I use to make a quick and interactive splash screen in flutter.

Prerequisites

  • Basic knowledge of flutter
  • Basic knowledge of android

Overview

In some cases we want to add an interactive splash screen to our app to prompt the user for different states, such as no internet connection. But just creating a splash widget may not be as satisfactory because flutter takes some time to draw its first frame when the app is launched. So today we'll be combining flutter splash screen with native android splash to get a quick and interactive splash screen.

Let's Get Started

Flutter Side

1. Create a new flutter project and open it in an IDE of your choice.

2. Go to the pubspec.yaml file and specify the assets directory as following:

flutter:
  # ... other properties here
  assets:
    - assets/images/
Enter fullscreen mode Exit fullscreen mode

Also change the dart SDK version constraints to enable null safety:

environment:
  sdk: ">=2.12.0 <3.0.0"
Enter fullscreen mode Exit fullscreen mode

3. Create a folder assets in the project root directory. And paste this image as "logo_flutter.png" in it.

4. Create a new dart file "splash_page.dart" in the "lib" folder and paste the following code in it:

import 'package:flutter/material.dart';

class SplashPage extends StatefulWidget {
  @override
  _SplashPageState createState() => _SplashPageState();
}

class _SplashPageState extends State<SplashPage> {
  @override
  void initState() {
    WidgetsBinding.instance?.addPostFrameCallback((_) => _afterBuild(context));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Center(
        child: Image.asset('assets/images/logo_flutter.png'),
      ),
    );
  }

  void _afterBuild(BuildContext context) {
    showModalBottomSheet(
      context: context,
      isDismissible: false,
      enableDrag: false,
      barrierColor: Colors.transparent,
      backgroundColor: Colors.blue,
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.only(
        topLeft: const Radius.circular(25),
        topRight: const Radius.circular(25),
      )),
      builder: (builderContext) {
        return SizedBox(
          height: 100,
          child: Padding(
            padding: EdgeInsets.all(16),
            child: Center(
              child: ElevatedButton(
                style: ElevatedButton.styleFrom(
                  primary: Colors.white,
                  onPrimary: Colors.blue,
                ),
                onPressed: () => Navigator.pop(context),
                child: Text('Dismiss'),
              ),
            ),
          ),
        );
      },
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

In the above code, we schedule our _afterBuild method to be called after the build method, inside the initState callback. The _afterBuild method will display a modal bottom sheet after the splash page has been drawn. Which can be dismissed by pressing the dismiss button.

5. Go to main.dart file and replace the existing code with following.

import 'package:flutter/material.dart';
import 'splash_page.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter App',
      debugShowCheckedModeBanner: false,
      home: SplashPage(),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

The SplashPage widget has been passed as the home parameter, meaning flutter will show the SplashPage when our app is launched.

Android Side

6. For the android side we will need to create resolution aware image assets for our splash logo. Open the Image Baker website in your browser. Drop the the "logo_flutter.png" image you downloaded earlier. The site will generate the assets for you. Go ahead and download them by clicking on the Android button.

7. Extract the folder somewhere and you will find several drawable folders inside the extracted folder. These folders tell android which asset to use for different density displays. Copy all the drawable folders and paste them inside the {your_project}/android/app/src/main/res folder.

8. Now we need to tell android to use our newly added asset. Open the "launch_background.xml" file in the "res/drawable" folder and replace the contents with following:

<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white" />

    <item>
        <bitmap
            android:gravity="center"
            android:src="@drawable/logo_flutter" />
    </item>
</layer-list>
Enter fullscreen mode Exit fullscreen mode

Make sure you are using the correct drawable resource name. Flutter creates a drawable-v21 variant by default for "launch_background.xml". If you don't need it for anything else delete the drawable-v21 folder or the "launch_background.xml" in it.

9. Now that we have added all the assets we need to make sure that the splash image size for our flutter splash and native android splash is the same. Open "logo_flutter.png" inside the res/drawable-xxxhdpi folder. Note the size of the image, we will need our flutter splash image to match the size of this image.

For xxxhdpi an image of 640px will be drawn as 1 inch on the device screen, while for flutter an image of 160 logical pixels will occupy 1 physical inch.

So we can calculate the size needed for flutter splash with the following equation:

h = (height of the xxxhdpi image) / 640 * 160
Enter fullscreen mode Exit fullscreen mode

Where h is the calculated height for the flutter splash image. Go to "splash_page.dart" and add the calculated height to the image.

@override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: Center(
        child: Image.asset(
          'assets/images/logo_flutter.png',
          height: 168.94,  // calculated height in my case
        ),
      ),
    );
  }
Enter fullscreen mode Exit fullscreen mode

Conclusion

And that's it we're done. Go ahead and run the application to watch your custom splash screen in action! Now we can discuss the pros and cons of this approach.

Pros

You get an instantaneous splash screen that is visible the moment your app launches. The splash becomes interactive when the flutter splash widget is drawn.

Cons

There is a slight blink when flutter draws its first frame. The lag is unacceptably long in development mode but it turns to only a slight blink in release mode. You can try to further optimize your flutter splash image by using resolution aware image assets.


That concludes this tutorial. I have hosted an example project on GitHub for anyone who is interested. I can't wait to see your feedback in the comments below. I hope to see you folks next time with more interesting content.

💖 💪 🙅 🚩
muiz6
M Muiz Hassan

Posted on May 30, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related