How to Use the Flutter Native Splash Screen: A Complete Guide for Android and iOS

Flutter displays a native splash screen using platform-specific resources—Android drawables and iOS storyboards—that automatically disappear once the first Flutter frame renders.

The flutter/flutter repository provides a built-in mechanism for showing a native splash screen during app startup. This lightweight placeholder UI is drawn by the platform before any Dart code executes, ensuring users see immediate visual feedback while the Flutter engine initializes.

What Is the Flutter Native Splash Screen?

A Flutter native splash screen is a platform-rendered view that appears instantly when the app launches, before the Flutter engine has finished loading. Because it is drawn by Android or iOS rather than Flutter, it avoids the blank white screen that would otherwise appear during initialization. The native splash is automatically removed once the first Flutter frame is rendered, creating a seamless transition into the app.

How the Flutter Native Splash Screen Works on Android

Android Implementation Details

On Android, the splash screen is implemented as a window background drawable that the system displays immediately upon activity launch. The FlutterActivity (or FlutterFragment) reads this drawable via the SplashScreenDrawable class defined in the engine.

According to the source code in engine/src/flutter/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java (lines 1310–1315), the engine checks for a metadata entry in the Android manifest to locate the drawable resource. Once the first Flutter frame renders, the engine calls the removal APIs to dismiss the splash view.

Configuring the Android Native Splash Screen

To configure the splash screen, you must define a launch theme in your Android project that references a drawable resource.

First, declare the metadata in android/app/src/main/AndroidManifest.xml:

<application
    android:label="my_app"
    android:icon="@mipmap/ic_launcher">
    <activity
        android:name=".MainActivity"
        android:exported="true"
        android:theme="@style/NormalTheme">
        <!-- Points to the splash drawable -->
        <meta-data
            android:name="io.flutter.embedding.android.SplashScreenDrawable"
            android:resource="@drawable/launch_background"/>
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
</application>

Next, define the themes in android/app/src/main/res/values/styles.xml:

<resources>
    <!-- Theme shown while the Flutter engine boots -->
    <style name="LaunchTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/launch_background</item>
    </style>

    <!-- Theme used after the engine is ready -->
    <style name="NormalTheme" parent="Theme.AppCompat.NoActionBar"/>
</resources>

Finally, create the drawable at android/app/src/main/res/drawable/launch_background.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/primary"/> <!-- Background color -->
    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/launch_image"/> <!-- Optional logo -->
    </item>
</layer-list>

The engine automatically removes this drawable once the first Flutter frame renders, as implemented in FlutterActivityAndFragmentDelegate.java.

How the Flutter Native Splash Screen Works on iOS

iOS Implementation Details

On iOS, the native splash screen is handled by a launch storyboard or static image set that the system displays before the FlutterViewController initializes. The engine creates a default splash view in engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm (lines 336–345) via the loadDefaultSplashScreenView method.

Once the Flutter engine renders the first frame, the engine calls removeSplashScreenWithCompletion: (lines 629–648 in the same file) to fade out and remove the native view.

Configuring the iOS Native Splash Screen

To customize the iOS splash screen, modify the launch storyboard in your Xcode project:

  1. Open ios/Runner.xcworkspace in Xcode.
  2. Select Runner/Assets.xcassets and add your launch images, or edit LaunchScreen.storyboard to design your layout.
  3. Ensure Info.plist references the storyboard:
<!-- ios/Runner/Info.plist -->
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>

For advanced use cases, you can provide a custom splash view programmatically from Dart by accessing the underlying view controller:

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Custom splash configuration can be handled via platform channels
  // or by modifying the native code directly in FlutterViewController.mm
  
  runApp(const MyApp());
}

The native view added by loadDefaultSplashScreenView in FlutterViewController.mm is automatically removed after the first frame renders.

Flutter Native Splash Screen Lifecycle

The native splash screen follows a strict three-phase lifecycle managed by the Flutter engine:

  1. App Launch – The platform (Android or iOS) immediately displays the launch theme background or launch storyboard before any Flutter code executes.
  2. Engine Initialization – The FlutterActivity (Android) or FlutterViewController (iOS) loads the splash view via SplashScreenDrawable or loadDefaultSplashScreenView.
  3. First Frame Render – Once the Flutter engine renders the first frame, the engine calls the platform-specific removal APIs (removeSplashScreenWithCompletion: on iOS or the equivalent Android delegate methods), exposing the Flutter UI.

Summary

  • The Flutter native splash screen is a platform-drawn view that appears during engine initialization, preventing blank screens at startup.
  • On Android, configure the splash screen via launch_background.xml, LaunchTheme, and the io.flutter.embedding.android.SplashScreenDrawable metadata in AndroidManifest.xml.
  • On iOS, customize the LaunchScreen.storyboard or launch images in Assets.xcassets, referenced by UILaunchStoryboardName in Info.plist.
  • The engine automatically removes the native splash after the first frame renders, as implemented in FlutterActivityAndFragmentDelegate.java (Android) and FlutterViewController.mm (iOS).

Frequently Asked Questions

How do I change the background color of the Flutter native splash screen on Android?

Modify the launch_background.xml drawable in android/app/src/main/res/drawable/. Add a solid color item using <item android:drawable="@color/your_color"/> or specify a hex color directly. Ensure the color is defined in colors.xml or styles.xml, and reference it in your LaunchTheme window background.

Can I use a custom widget as the splash screen on iOS?

While the initial iOS splash must be a native storyboard or image (since Dart isn't running yet), you can replace the default splash view programmatically once the engine starts. In FlutterViewController.mm, the engine calls loadDefaultSplashScreenView by default, but you can assign a custom view via setSplashScreenView: before runApp completes. However, for most cases, customizing the LaunchScreen.storyboard in Xcode is the recommended approach.

When exactly does the native splash screen disappear?

The native splash screen disappears immediately after the Flutter engine renders the first frame of your application. On Android, FlutterActivityAndFragmentDelegate monitors the first frame and removes the SplashScreenDrawable. On iOS, FlutterViewController invokes removeSplashScreenWithCompletion: once the engine signals that rendering has begun. This ensures a seamless transition from the native placeholder to the Flutter UI.

What is the difference between LaunchTheme and NormalTheme in Flutter Android apps?

LaunchTheme is the theme applied to your MainActivity in the AndroidManifest.xml that displays the native splash screen. It typically sets android:windowBackground to your splash drawable and is used only during the brief period before the Flutter engine is ready. NormalTheme is the theme applied after the engine initializes and the first frame renders, controlling the appearance of the Flutter UI (such as status bar color and system UI visibility). You switch from LaunchTheme to NormalTheme programmatically once Flutter is ready.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →