React Native Splash Screen on Android
Spoiler: Native internals
I could have used the following title for this article: “React Native Splash Screen done right on Android”. And you could have asked me, why done right? Who are you to say how to do it right? Well, it’s not you it’s me (or something like that!). It is actually Google and they know some things about Android. First of all, I’d like to suggest you to watch the following 3 minutes video:
Now, in order to add a splash screen into a React Native app (on the Android side), let’s follow their suggestions.
First attempt
The example app of this article does not have a white background by default, so having the transition from white to blueish is probably not really what we want:
Let’s apply some concepts from the video including handling the status bar:
Note: With colorPrimaryDark
you can change the status bar color on Android without waiting for the JS to load. You won’t even need to use the StatusBar
component for it.
With that we got the following effect:
Much better with a couple of lines, but let’s proceed.
Second attempt
Ok, now we want to add an image to the splash screen. We can use windowBackground
as it was explained in the video we watched (right?) just a few moments ago. First, we need to create a drawable
file:
Then let’s update our styles to add the SplashTheme
:
We modify our AndroidManifest.xml
to change the default theme of our MainActivity
:
// AndroidManifest.xml<activity
android:name=".MainActivity"
...
android:theme="@style/SplashTheme">
And finally we change our MainActivity
to switch to the default theme when the app starts:
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
}
Everything we did here so far is from the Google’s video. All of it. This is the final result:
I was not fully satisfied with it. There is still an empty blue screen in the middle (because the JS and everything else needed by React Native is still loading). So the following is the extra React Native mile I came up with.
Final attempt
The idea is:
- Show the splash screen while loading JS without mounting the React default view
- When the JS is ready, mount the React view using a native fade-in animation
Note: The following code is not documented so it might change in future versions of React Native.
We are gonna override the createReactActivityDelegate
method from theReactActivity
. This is to defer adding the ReactRootView
so then we can have a nice fade-in effect (we will call setContentView
later). Thus, inside of our MainActivity
let’s place this piece of code:
After that, we are going to add the following method (where the magic happens):
And we are also going to create a small native module that we will use from the JS side:
Anywhere in our JS side, depending on ours app needs we can call that method:
// JS sideimport { NativeModules } from 'react-native';
const RNSplashScreen = NativeModules.RNSplashScreen;
RNSplashScreen.hide();
And with that, we got the one I was looking for:
Note: Another benefit from this approach is that we do not have to use any extra Activity or Dialog.
It took me quite some time but I am really happy with the final result and if you would like the same, feel free to use that in your React Native apps for a delightful Android splash screen experience.
Thanks for reading and happy coding!