DEV Community

Cover image for Custom Native Splash Screen Flutter: flutter_native_splash Guide
PEAKIQ
PEAKIQ

Posted on • Originally published at peakiq.in

Custom Native Splash Screen Flutter: flutter_native_splash Guide

Originally published on PEAKIQ

Source: https://www.peakiq.in/blog/how-to-implement-a-custom-native-splash-screen-in-flutter



How to Add a Native Splash Screen in Flutter

A splash screen is the first thing users see when they open your app. In Flutter, you can create a native splash screen that appears instantly — before Flutter even loads — using the flutter_native_splash package. This gives your app a polished, professional feel from the very first frame.

In this tutorial you will configure colors, apply the splash to both iOS and Android, and control exactly when the splash disappears using preserve() and remove().


Step 1 — Install the Package

Add flutter_native_splash to your pubspec.yaml under dev_dependencies:

dev_dependencies:
  flutter_native_splash: ^2.4.7
Enter fullscreen mode Exit fullscreen mode

Then fetch it:

flutter pub get
Enter fullscreen mode Exit fullscreen mode

Step 2 — Create the Configuration File

Create a file named flutter_native_splash.yaml in your project root and add:

flutter_native_splash:
  color: "#000000"
  fullscreen: true

android_12:
  color: "#000000"
  icon_background_color: "#111111"
Enter fullscreen mode Exit fullscreen mode

This configuration sets a black background, enables fullscreen mode, and applies correct styling for Android 12 and above — which has its own splash API that requires separate configuration.

Once the file is ready, generate the native splash assets:

flutter pub run flutter_native_splash:create
Enter fullscreen mode Exit fullscreen mode

Re-run this command every time you update the YAML file. Changes to the configuration are not picked up automatically.


Step 3 — Control the Splash Programmatically

By default, the splash disappears as soon as Flutter finishes rendering its first frame. In most real apps, you need it to stay visible longer while async work completes — loading user data, initializing storage, fetching remote config, or validating a session.

The package provides two methods for this:

  • FlutterNativeSplash.preserve() — holds the splash open until you are ready
  • FlutterNativeSplash.remove() — dismisses the splash and reveals the app UI

Full working example

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

void main() {
  WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
  FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
  runApp(const MainApp());
}

class MainApp extends StatefulWidget {
  const MainApp({super.key});

  @override
  State<MainApp> createState() => _MyAppState();
}

class _MyAppState extends State<MainApp> {
  @override
  void initState() {
    super.initState();
    _initializeApp();
  }

  Future<void> _initializeApp() async {
    // Replace this with your real initialization logic
    await Future.delayed(const Duration(seconds: 3));
    FlutterNativeSplash.remove();
  }

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.white,
        body: Center(
          child: Text("Native Splash"),
        ),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

How it works

WidgetsFlutterBinding.ensureInitialized() must be called before preserve() because the splash system hooks into the widget binding lifecycle. Passing the binding reference to preserve() tells the package to hold the splash until you explicitly call remove().

In _initializeApp, replace Future.delayed with your actual startup work — API calls, shared preferences initialization, feature flag fetches, or user session validation. Call remove() only after all of it is complete.


Configuration Options

The YAML file supports more than just background color. Common options worth knowing:

Option What it does
color Background color in hex
image Path to a logo or icon, e.g. assets/logo.png
fullscreen Hides the status bar during the splash
color_dark Background color when the device is in dark mode
image_dark Separate image for dark mode
android_12.color Android 12+ specific background color
android_12.icon_background_color Background behind the icon on Android 12+

iOS and Android can each have separate image and color values, so the splash can match each platform's conventions exactly.


Tips for Production

  • Add your app logo with image: assets/logo.png and rerun the creation command
  • Configure color_dark and image_dark for dark mode support
  • Use different images or colors per platform by adding android: and ios: sections
  • Add a background gradient on Android by pointing to a custom drawable file
  • Always rerun flutter pub run flutter_native_splash:create after any YAML change

Result

With this setup in place, the native splash loads instantly on app open, stays visible while initialization completes, and dismisses cleanly when the app is ready — giving users a smooth, professional experience from the very first frame.


Top comments (0)