---
url: 'https://simonerescio.it/en/2014/05/phonegap-android-splashscreen-application'
title: 'HelloSplash, Phonegap Android SplashScreen'
author:
  name: Simone Rescio
  url: 'https://simonerescio.it/en/about-me/'
date: '2014-05-04T20:13:55+02:00'
modified: '2026-04-19T18:55:23+02:00'
type: post
categories:
  - PhoneGap
tags:
  - 9-patch
  - android
  - child theme
  - CSS
  - css3
  - github
  - hellosplash
  - phonegap
  - scale
  - splash screen
  - splashscreen
  - spring in
  - spring out
  - XML bitmap
image: 'https://simonerescio.it/wp-content/uploads/2014/05/phonegap-android-splashscreen.png'
published: true
---

# HelloSplash, Phonegap Android SplashScreen

Like for the first encounter between two strangers, a critical aspect for a mobile app when it meets our new users, whether we like to admit it or not, is the first impression.

The splash screen is the very first thing our users got to judge our app the very first time they launch it, the way we make it blend with our app UI, possibly giving it a functional role, can greatly increase the overall perceived quality, and if done poorly it can as well obtain the opposite effect.

*Notice that the following procedure is executed with PhoneGap version 3.3.0, thus valid from version 3 and above.*

[![Cordova Hello World application startup](https://simonerescio.it/wp-content/uploads/2014/05/hellosplash-outofthebox.gif)](https://simonerescio.it/en/2014/05/phonegap-android-splashscreen/hellosplash-outofthebox/)*Cordova Hello World application startup*

So the first thing I did was to create an Hello World project, which I named [HelloSplash on GitHub](https://github.com/srescio/hellosplash/releases), to see how this is handled, assuming such a common feature would come just out of the box, so I just build the project and launch it in an Android 2.3 emulator ([HelloSplash tag v1.0.0](https://github.com/srescio/hellosplash/tree/1.0.0)).

Not nice, at all, a pitch black screen until my app UI renders in a flash is not what I’m looking for.

Next step I did was to look for some documentation about how to handle a splash screen and came across the official [splashscreen API reference](http://docs.phonegap.com/en/3.3.0/cordova_splashscreen_splashscreen.md.html#Splashscreen).

After following the setup instruction I created all the different resolutions of my test image, a trick to handle this quickly is to create the main document starting for the XHDPI resolution, then you can obtain all the resolutions by downsampling during the export operation with following percentages :

- *LDPI* : 38%

- *MDPI*: 50%

- *HDPI*: 75%

- *XHDPI*: 100%

Now that we have the images we put them into their [relevant folders](http://docs.phonegap.com/en/3.3.0/config_ref_images.md.html#Icons%20and%20Splash%20Screens_splash_screens_for_the_android_platform) which are :

```
/hellosplash/HelloSplash/platforms/android/res/drawable-ldpi/splash.png
/hellosplash/HelloSplash/platforms/android/res/drawable-mdpi/splash.png
/hellosplash/HelloSplash/platforms/android/res/drawable-hdpi/splash.png
/hellosplash/HelloSplash/platforms/android/res/drawable-xhdpi/splash.png
```

Rebuild the app, and nothing changed…why? We did followed all the official instructions but comes out something is wrong on this line of the documentation :

> In config.xml in the project’s www directory, add the following preferences

Fact is that in the project there are three *config.xml* :

```
/hellosplash/HelloSplash/config.xml
/hellosplash/HelloSplash/www/config.xml
/hellosplash/HelloSplash/platforms/android/res/xml/config.xml
```

The one that will actually be executed by Android is the last one of course, the docs advise us to edit the second because they think that one will be used to update the third during the build process but it is completely ignored, what gets the work done is the first one, so the file we want to edit in order to update the compiled file is *hellosplash/HelloSplash/config.xml* with the following : 

```
<preference name="SplashScreen" value="splash" />
<preference name="SplashScreenDelay" value="10000" />
```

[![The PhoneGap splash screen plugin kicks in midway through app startup](https://simonerescio.it/wp-content/uploads/2014/05/hellosplash-officialdocs.gif)](https://simonerescio.it/en/2014/05/phonegap-android-splashscreen/hellosplash-officialdocs/)*The PhoneGap splash screen plugin kicks in midway*

Rebuild the app and now we do have a splash screen, however we still have the first pitch black screen too.  

([HelloSplash tag v1.1.0](https://github.com/srescio/hellosplash/tree/1.1.0))  

Also you can notice how the image fades in but does not fade out, even calling the *navigator.splashscreen.hide()* method directly the screen would just disappear in a bump, revealing our UI in a brute way.

Unfortunately the plugin doesn’t provide any mean of customization of these aspects. If we want a more “professional” and appealing feeling to the splash screen we will have to get our hands dirty outside the box of the *www* folder.

- [1. Startup phases of a PhoneGap App on Android](#startup-phases-of-a-phonegap-app-on-android)
- [2. Change the Android application window background with native child theme](#change-the-android-application-window-background-with-native-child-theme)
- [3. Prevent WebView and HTML loading flicker with a short delay](#preventwebview-and-html-loading-flicker-with-a-short-delay)
- [4. HTML stand in for splash screen fade out](#html-stand-in-for-splash-screen-fade-out)
- [5. XML bitmap for image metadata](#xml-bitmap-for-image-metadata)
- [6. Recap, customizing callbacks and effects](#recap-customizing-callbacks-and-effects)

## Startup phases of a PhoneGap App on Android

To understand how to fix the issue we need to understand the flow and steps of the application startup process, which is actually a five steps process and each displays to the user a different screen in fast succession :

- Android application window

- Activity window fade in

- Empty WebView frame

- HTML document loading, white screen

- HTML page rendered, CSS and JS resources have been loaded and executed

Before we start addressing these points give a peek to the [Android UI Themes official documentation](http://developer.android.com/guide/topics/ui/themes.html), nothing to be scared about.

## Change the Android application window background with native child theme

The first black screen is the Application Window background, the empty native Java container that wraps our HTML web app, and the color we are seeing comes from the native theme the app is assigned.

Every PhoneGap project we create ships with a default theme declared in the **AndroidManifest.xml**, it’s the last attribute of the **activity** tag :

```
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" android:windowSoftInputMode="adjustPan" package="com.coolappz.HelloSplash" xmlns:android="http://schemas.android.com/apk/res/android">
    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
    <uses-permission android:name="android.permission.INTERNET" />
    <application android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:name="HelloSplash" android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    [...]
</manifest>
```

Our app is composed of a single activity that uses the **Theme.Black.NoTitleBar.**

In order to override some aspects of this theme to fit our needs we are going to create a [child theme](http://developer.android.com/guide/topics/ui/themes.html#DefiningStyles) that refers to this default theme as parent and change just what we need, basically overriding things as we would do with CSS specificity.

As the docs says the file name that stores our styles can be anything, but for simplicity sake I recommend to name it just ***style.xml*** to avoid confusion, so here’s the full path and content, we’ll use the same color present in our splash screen images:

```
hellosplash/HelloSplash/platforms/android/res/values/style.xml
```

```
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="hellosplash_window">#b9ff74</color>
    <style name="HelloSplashTheme" parent="android:style/Theme.Black.NoTitleBar">
        <item name="android:windowBackground">@color/hellosplash_window</item>
    </style>
</resources>
```

Now to allow our app to use our theme’s styles instead of the default theme in the **AndroidManifest.xml** we need to change the  **activity** **tag’s last attribute**  from:

```
android:theme="@android:style/Theme.Black.NoTitleBar"
```

to

```
android:theme="@style/HelloSplashTheme"
```

Notice how after the At symbol we omit “*android:*” because we’re not referring to a global style included by default in the Android OS anymore but to our theme name stored in our *style.xml* file.

## Prevent WebView and HTML loading flicker with a short delay

[![Android PhoneGap app startup five phases](https://simonerescio.it/wp-content/uploads/2014/05/hellosplash-phases.gif)](https://simonerescio.it/en/2014/05/phonegap-android-splashscreen/hellosplash-phases/)*All the five phases the application goes through*

If we comment the last two lines we added in the project root *config.xml* to deactivate the splash screen plugin temporarily and build the app we’re going to see clearly all the phases enumerated before. 

We can see now that the first colors that welcomes us is not the pitch black like before but the color we just defined in our custom theme, also without the splash screen we can see that the impression we had of the image provided with the plugin fading in was wrong as it’s actually the whole activity window that fades in, which happens to show our splash image as instructed in the *config.xml*.

But we notice two more effects, after the activity fade in follows a black/white flash then HTML page suddenly appears, what happens here is that WebView gets initialized into the activity window, then starts loading the assets thus showing us the blank HTML page, finally the resources are parsed and our web app appears.

These steps, listed above 3 through 5, were masked by the splash screen plugin for which we didn’t put an hide callback in our JavaScript, so by the time we had set for it to last we’re presented with step 5, when the page is already up and running.

Like the official documentation of the plugin recommends, we do not want the splash screen to stay up for the whole time we set in the *config.xml*, instead we should make it disappear as soon as our UI is ready, or better when the **document** is ready.

But if the splash screen gets hidden upon *document ready* there’s still an instant of black screen before our HTML appears, after several test I discovered that one second and half of delay after the *document ready* callback is safe to ensure that the page below is actually visible, so let’s add the following lines inside the **receivedEvent** function of **www/index.js** :

```
$(document).ready(function(){
            setTimeout(function(){
                navigator.splashscreen.hide();
           },1500);
        });
```

When the splash screen goes away we have the page up and running below, still it does without any fade effect which is not very nifty, but at this point of the work we are on web technology field, we now have full power at our hand to handle this 🙂 .

## HTML stand in for splash screen fade out

The first thing we would want in our HTML is a *div* that has as background image the one we use as splash screen, so that when we hide the splash screen we do not notice any difference as we’re still seeing the same image, only now we can apply a fade out animation to the HTML specular element.

Let’s copy the ***drawable-xhdpi/splash.png*** image under our ***www/img/*** directory to be accessible via CSS, now in *index.html* we want the first child of the body to be :

```
<div id=“splash”></div>
```

to apply the following styles : 

```
#splash {
    background-attachment: scroll;
    background-color: #ecffb1; 
    background-image: url(../img/splash.png);
    background-position: center center;
    background-repeat: no-repeat;
    background-size: 450px auto;
    display: block;
    height: 100%;
    width: 100%;
    position: fixed;
    z-index: 10;
}
```

then in the time out function we just created let’s add a fadeOut to the div : 

```
$(document).ready(function(){
            setTimeout(function(){
                navigator.splashscreen.hide();
                $('#splash').fadeOut();
            },1500);
        });
```

[![Startup with custom background color and HTML splash replica fade out](https://simonerescio.it/wp-content/uploads/2014/05/hellosplash-colortofade.gif)](https://simonerescio.it/en/2014/05/phonegap-android-splashscreen/hellosplash-colortofade/)*Startup with custom color, fade in with matching splash screen, then fade out of HTML splash replica*

Now the application launches with  our color, our logo and fades in nicely, then fades out to reveal our web app.  

([HelloSplash tag v1.2.0](https://github.com/srescio/hellosplash/tree/1.2.0))  

Almost what we want, you noticed an issue right?

The aspect ratio of the image changes, what’s happening is that we’re using for the splash screen a set of images thought to be bigger than the screen in order to fill all the visible area, but on Android any native UI element that shows a picture if not instructed on how to handle such content will automatically stretch it to fill all it’s available space, in the case of [9-patch images](https://developer.android.com/tools/help/draw9patch.html) suggested in the plugin page only the instructed areas would be stretched leaving the rest of the content centered.

I struggled a lot to work even with third party tools to elaborate a working 9-patch but with little luck, and if we desire to use a complex graphic element instead of a full color or simple logo this approach would be limited, so next step we’ll make behave our images.

## XML bitmap for image metadata

To tell the native splash screen to not stretch our image and keep it centered in the visible area we can use [XML bitmap](http://developer.android.com/guide/topics/resources/drawable-resource.html#XmlBitmap) files to specify metadata about our images.

In each drawable-* directory we’ll have to update the images names as they cannot match the XML file name, also because each name gets stored during build phase to create a resource ID we should use a new name for the XML files as well :

```
/hellosplash/HelloSplash/platforms/android/res/drawable-ldpi/splash_image.png
/hellosplash/HelloSplash/platforms/android/res/drawable-ldpi/splashscreen.xml
```

All the xml files shall have the same content, where we specify to not stretch the image and supply its path, that being in the same directory of the xml is the name of the png alone :

```
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
        android:gravity="center"
        android:src="@drawable/splash_image" />
```

Now that we changed the files names we must update the root *config.xml* too in order to make it fetch our XML files, which will tell the system how to handle the images they point to :

```
<preference name="SplashScreen" value="splashscreen" />
```

Now that our images do not get stretched lets adjust the background-size of our HTML replica :

```
#splash {
    background-attachment: scroll;
    background-color: #ecffb1; 
    background-image: url(../img/splash.png);
    background-position: center center;
    background-repeat: no-repeat;
    background-size: 900px auto;
    display: block;
    height: 100%;
    width: 100%;
    position: fixed;
    z-index: 10;
}
```

[HelloSplash tag v1.3.0](https://github.com/srescio/hellosplash/tree/1.3.0)

[![Final result with all splash screen fixes applied](https://simonerescio.it/wp-content/uploads/2014/05/hellosplash-xmlbitmap.gif)](https://simonerescio.it/en/2014/05/phonegap-android-splashscreen/hellosplash-xmlbitmap/)*Final result with all fixes applied*

## Recap, customizing callbacks and effects

Let’s review all the necessary steps to address each phase of the startup process :

- To change the default Application background create a native child theme *style.xml* and update the *AndroidManifest.xml*

- Enable the SplashScreen PhoneGap plugin by adding the two parameters, duration and path, in the project root *config.xml*. The path must have the name of the XML bitmap file we’re going to create to tell to not stretch our images that will reside with the XML itself in each *drawable-** folder

- In the *index.js* we will call the hide method to remove the native splash screen after a 1,5 seconds delay inside the *document ready* callback to ensure that our HTML is visible, at the same time we will fadeOut the HTML replica of our native splash screen to gracefully present our web app.

[![Infographic of PhoneGap Android app startup phases and custom splash screen fixes](https://simonerescio.it/wp-content/uploads/2014/05/phonegap-android-splashscreen-infographic.png)](https://simonerescio.it/en/2014/05/phonegap-android-splashscreen/phonegap-android-splashscreen-infographic/)*Infographic with PhoneGap Android App startup phases and relevant fixes applied*

Regarding the timing to hide the splash screen and fade out the HTML replica, I’m using the *document ready* function just as an example.

If your app needs to fetch some data, either from the web or from internal storage, or you need to startup any kind of service before the UI is rendered, you can call the hide and fadeOut functions with a custom callback in response to the correct event.

Also you can customize the HTML splash replica fade out how you want, you could mimic the system **spring out** effect by using a CSS3 scale animation from 1 to 0.7 together with the opacity fade from 1 to 0

or you could do the other way around, your web app UI **spring in**, placing itself on top of the HTML splash replica

it’s really up to you 🙂 .

 [](https://mastodon.social/share?text=http%3A%2F%2Fsresc.io%2Fo&title=HelloSplash%2C%20Phonegap%20Android%20SplashScreen)[](https://www.linkedin.com/sharing/share-offsite/?url=http%3A%2F%2Fsresc.io%2Fo)[](https://simonerescio.it/en/2014/05/phonegap-android-splashscreen-application)[](https://reddit.com/submit?url=http%3A%2F%2Fsresc.io%2Fo&title=HelloSplash%2C%20Phonegap%20Android%20SplashScreen)[](https://api.whatsapp.com/send?text=HelloSplash%2C%20Phonegap%20Android%20SplashScreen http%3A%2F%2Fsresc.io%2Fo)[](https://bsky.app/intent/compose?text=HelloSplash%2C%20Phonegap%20Android%20SplashScreen%20http%3A%2F%2Fsresc.io%2Fo)[](https://telegram.me/share/url?url=http%3A%2F%2Fsresc.io%2Fo&text=HelloSplash%2C%20Phonegap%20Android%20SplashScreen)[](https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fsresc.io%2Fo)

