[Flutter] Removing the Default White Flash with flutter_native_splash
When you launch a Flutter app, you might notice a brief white flash before your custom splash screen appears. This is the native splash screen displayed by the OS while the Flutter engine is loading. Its default is white, so it stands out.
This post covers how to change that screen with the flutter_native_splash package.
Why Do You See a White Screen?
The startup flow of a Flutter app is as follows:
App Launch → [Native Splash] → Flutter Engine Loading → [Flutter Widget Rendering]
Because Dart code cannot run before the Flutter engine is loaded, the OS displays a static screen at the native level. This corresponds to launch_background.xml on Android and LaunchScreen.storyboard on iOS.
If your custom splash screen is dark, the transition from White → Custom Splash becomes very noticeable.
Solution
1. Install the Package
flutter pub add flutter_native_splash
2. Configure pubspec.yaml
Add the configuration to pubspec.yaml. You can also put it in a separate flutter_native_splash.yaml file at the project root.
flutter_native_splash:
color: "#009CCC" # Background color (matching your splash screen)
image: assets/images/logo.png # Logo to display in the center (optional)
android: true
ios: true
# Android 12+ ignores the settings above, so configure it separately
android_12:
color: "#009CCC"
image: assets/images/logo.png # clipped to a circle in the center
flutter:
uses-material-design: true
# ...
Tip: If your custom splash uses a gradient, set the mid-tone color as the background color for a smoother transition. To use the gradient itself, put a gradient image in
background_imageinstead ofcolor(not on Android 12+).
3. Generate the Native Splash
dart run flutter_native_splash:create
This command modifies the following native files:
- Android:
launch_background.xml,styles.xml - iOS:
LaunchScreen.storyboard,Assets.xcassets
4. Modify main.dart - Preserve Splash
By default, the native splash is removed when Flutter draws its first frame. Calling preserve() keeps the native splash visible until you call remove().
import 'package:flutter_native_splash/flutter_native_splash.dart';
Future<void> main() async {
// Prepare Flutter bindings + Preserve native splash
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
// Initialize Firebase, SDKs, etc.
await Firebase.initializeApp();
runApp(MyApp());
}
5. Remove in the Splash Screen
Remove the native splash in the initState() of your custom Flutter splash widget.
import 'package:flutter_native_splash/flutter_native_splash.dart';
class _SplashScreenState extends State<SplashScreen> {
void initState() {
super.initState();
// Remove native splash → Flutter splash becomes visible
FlutterNativeSplash.remove();
// Business logic like server checks or authentication...
_checkServerAndAuth();
}
}
Final Execution Flow
- App Launch
- Native Splash (#009CCC + Logo) ← Instead of the white screen!
- Flutter Engine Loading (Native splash persists)
- Flutter Splash Widget
initState()executes FlutterNativeSplash.remove()is called- Custom Splash (Gradients + Animations)
- Main Screen
Native Splash vs. Flutter Splash
| Feature | Native Splash | Flutter Splash |
|---|---|---|
| Execution Timing | Before engine loads | After engine loads |
| Implementation | OS Level (XML, Storyboard) | Dart Widgets |
| Gradients | Only via a background image (not on Android 12+) | Supported |
| Animations | Not supported | Supported |
| Business Logic | Not possible | Possible (API calls, Auth) |
| Custom Fonts | Not supported | Supported |
Important Considerations
- Gradients: Use a gradient image in
background_image. Android 12+ doesn't support background images, so only solid colors work there. - Android 12+: Configure the
android_12section separately. The logo is clipped to a circle in the center of the screen. - Mandatory Removal: You must call
remove()afterpreserve(), otherwise the splash screen stays on screen. - No Dart Logic: Native splashes cannot execute Dart code like server checks.
- Apply Changes: You must re-run
dart run flutter_native_splash:createevery time you modify the configuration. - iOS Cache: Changes might not appear on iOS due to caching. The package README suggests uninstalling the app, restarting the device, and reinstalling.
Summary
flutter_native_splash changes the native splash background, and if needed, two calls control when it stays and when it goes:
// 1. Preserve in main()
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
// 2. Remove in the splash screen widget
FlutterNativeSplash.remove();