In Flutter, a splash screen is the first screen users see when they launch your app. It’s a crucial element for providing initial branding and preparing your app’s resources in the background. A well-implemented splash screen creates a polished user experience and can improve app perception.
What is a Splash Screen?
A splash screen, also known as a launch screen, is a brief visual presented to the user while an application is loading or initializing. It typically displays a logo, branding, or loading animation to inform the user that the app is starting up.
Why Implement a Splash Screen?
- Branding: Reinforces your app’s brand identity with a logo and color scheme.
- User Experience: Provides immediate feedback, making the app feel responsive.
- Loading Time: Masks initial loading processes, improving perceived performance.
Methods for Implementing a Splash Screen in Flutter
There are several ways to implement a splash screen in Flutter, each with its advantages. This guide covers native splash screens, using delays, and leveraging asynchronous tasks.
Method 1: Native Splash Screen (Recommended)
The most performant approach is to utilize the native splash screen provided by the underlying platform (Android/iOS). This ensures the splash screen is displayed almost instantly as the app launches.
Step 1: Add flutter_native_splash Dependency
Use the flutter_native_splash package, which simplifies the creation of native splash screens. Add it to your pubspec.yaml file:
dev_dependencies:
flutter_native_splash: ^2.3.8 # Use the latest version
Step 2: Configure flutter_native_splash in pubspec.yaml
Define your splash screen configurations within the same pubspec.yaml file:
flutter_native_splash:
color: "#FFFFFF" # Background color
image: assets/splash.png # Splash image
android_12:
image: assets/splash_android12.png # Android 12 adaptive icon
android: true
ios: true
Customize the following:
color: Background color of the splash screen.image: The path to your splash screen image asset.android_12: Configuration options specifically for Android 12 adaptive icons.android: Enable or disable the native splash screen on Android.ios: Enable or disable the native splash screen on iOS.
Step 3: Generate the Native Splash Screen
Run the following command in your terminal to generate the native splash screens based on your configuration:
flutter pub get
flutter pub run flutter_native_splash:create
This command will automatically generate the required files for Android and iOS platforms.
Step 4: Implement Code to Hide Splash Screen
After generating the native splash screen, you’ll need to programmatically remove it when your app is ready. You can use the following code in your main.dart file within the initState of your initial screen or after asynchronous operations:
import 'package:flutter/material.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Splash Screen Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
@override
void initState() {
super.initState();
initialization();
}
void initialization() async {
// Simulate app initialization processes
await Future.delayed(Duration(seconds: 3));
FlutterNativeSplash.remove();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: Center(
child: Text('App is Ready!'),
),
);
}
}
Here’s what the code does:
- In the
main()function, we callWidgetsFlutterBinding.ensureInitialized(). - In the
initState()method, we invoke an asynchronous functioninitialization(). - The
initialization()function simulates app initialization processes (e.g., loading data) usingFuture.delayed(). - Finally, we remove the native splash screen by calling
FlutterNativeSplash.remove().
Method 2: Using a Delayed Splash Screen in Flutter
This method uses a Flutter Widget to show a splash screen and delays navigating to the main app screen using Future.delayed. While simple, it might be less performant than using the native splash screen for the initial load.
Step 1: Create a Splash Screen Widget
Design a simple splash screen UI as a Flutter Widget.
import 'package:flutter/material.dart';
import 'main.dart'; // Import your main app file
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State {
@override
void initState() {
super.initState();
_navigateToMainScreen();
}
_navigateToMainScreen() async {
await Future.delayed(Duration(seconds: 3), () {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => MyHomePage()),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/splash.png', width: 150, height: 150), // Your logo
SizedBox(height: 20),
Text(
'My Awesome App',
style: TextStyle(fontSize: 24, color: Colors.white),
),
],
),
),
);
}
}
In this Widget:
Image.asset('assets/splash.png')displays a logo image.Future.delayedis used to delay navigation to the main screen.Navigator.pushReplacementreplaces the splash screen with the main app screen to prevent users from navigating back to the splash screen.
Step 2: Set the Splash Screen as the Initial Route
In your main.dart file, set the SplashScreen as the initial route for your app:
import 'package:flutter/material.dart';
import 'splash_screen.dart'; // Import your splash screen file
import 'home_page.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Splash Screen Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SplashScreen(), // Set SplashScreen as the initial route
);
}
}
In this code, the home property of MaterialApp is set to SplashScreen(), making it the first screen displayed when the app starts.
Method 3: Loading Data Asynchronously in Splash Screen
For loading initial data or performing asynchronous operations, a splash screen can be combined with a FutureBuilder. This approach ensures that data is loaded before displaying the main UI.
Step 1: Create a Splash Screen with Data Loading
Design a splash screen that performs an asynchronous task while it is visible. Use FutureBuilder to listen for the completion of this task.
import 'package:flutter/material.dart';
import 'home_page.dart';
import 'main.dart'; // Import your main app file
class SplashScreen extends StatefulWidget {
@override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State {
Future _loadData() async {
// Simulate loading data or any other async operation
await Future.delayed(Duration(seconds: 3));
// Here you might load configuration data, authenticate user, etc.
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blue,
body: FutureBuilder(
future: _loadData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// Once data loading is done, navigate to the main screen
return MyHomePage(); // Or navigate to your main screen widget
} else {
// While loading data, show the splash screen UI
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/splash.png', width: 150, height: 150), // Your logo
SizedBox(height: 20),
Text(
'Loading App...',
style: TextStyle(fontSize: 24, color: Colors.white),
),
SizedBox(height: 20),
CircularProgressIndicator(valueColor: AlwaysStoppedAnimation(Colors.white)),
],
),
);
}
},
),
);
}
}
Key aspects of this code:
- _loadData(): Asynchronously loads necessary data and configures the app.
- FutureBuilder: Displays a loading UI while
_loadDatais running, and navigates to the main screen once loading is complete.
Step 2: Setting Up as the Initial Route
Set the SplashScreen as the initial route as before:
import 'package:flutter/material.dart';
import 'splash_screen.dart';
import 'home_page.dart'; // Import your main app file
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Splash Screen Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SplashScreen(), // Set SplashScreen as the initial route
);
}
}
Best Practices for Splash Screens
- Keep it Short: Splash screens should ideally last no more than 2-3 seconds to avoid frustrating users.
- Native Implementation: Utilize the native splash screen for the best performance.
- Optimize Images: Ensure splash screen images are properly sized and optimized to reduce load times.
- Branding Consistency: Maintain consistent branding with your app’s overall theme.
Conclusion
Implementing a splash screen in Flutter enhances the user experience by providing immediate visual feedback and branding reinforcement while your app initializes in the background. The native splash screen approach (using flutter_native_splash) is recommended for optimal performance and a seamless loading experience. By following this guide, you can effectively implement splash screens that improve the initial perception and user satisfaction of your Flutter applications.