Introduction
Everyone wants his/her application to be beautiful and attractive for an eye of a user. And there are a lot of applications, at least desktop applications, mostly games that use splash screens. It’s nice and, moreover, while the splash screen is working, you can initialize your application. Many tutorials exist explaining how to begin Android programming and I won't repeat them here. You can find them all over the internet. So I will show only the programming stuff.
The Beginning
Create a new Android Eclipse project with the following settings:
Project name : AdvancedSplashDemo
Build target: I've set it to Android 2.1
Application name: Advanced Splash Demo
Package name: Advanced Splash Demo
Create Activity: MainActivity – it will be the application itself
So, as we don’t need a splash screen after it’s done, the first thought is to use another activity that will start the main activity and silently die after that. Let’s create a layout for the splash – it will be a linear layout and an Image View inside it. Create a new Android XML file "splash.xml" in appfolder/res/layout folder. Don’t make it fill parent, as we want it to be really as splash screen. The image view has to wrap a content too:
="1.0"="utf-8"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/TheSplashLayout"
android:layout_gravity="center"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/SplashImageView"
android:layout_gravity="center"
android:src="@drawable/lnxins"
>
</ImageView>
</LinearLayout>
Here the gravity attribute value is set to "center
" to make the splash to be at the center of the screen. Add some picture to the appfolder/res/drawable folder and press F5 on the project. I’ve added lnxins.png and as you can see, set it as the image view source.
So far, let’s look at the application manifest. It has now just one “.MainActivity
” activity set as a launcher. We’ll set it as default category and add another splash activity with a splash layout and will set it as the launcher. Open the manifest and open an application tab. For the main activity, change an Android intent category to default. Near application nodes press an “Add…” button, choose create a new element at top level and double click on Activity. For new activity, click on a “Name*” hyperlink and enter “SplashScreen
” class. In sources, a new class will be added for the splash activity. Next, press the “Add…” button again for the SplashScreen
node and add the intent filter. Again, for just added intent filter, add an action and a category.
Set the action to android.intent.action.MAIN
and the category to android.intent.category.LAUNCHER
. So the Splash screen activity will be run first. The manifest should look like the following:
="1.0"="utf-8"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yourname.main"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="SplashScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN"></action>
<category android:name="android.intent.category.LAUNCHER"></category>
</intent-filter>
</activity>
</application>
</manifest>
A Little Coding
Open SplashScreen.java class. Now it has overridden onCreate
method only. Override onTouchEvent
method to give the user a possibility to close splash screen at every moment. And don’t forget synchronization or you will have random crashes. Here’s the class code:
public class SplashScreen extends Activity {
private Thread mSplashThread;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
final SplashScreen sPlashScreen = this;
mSplashThread = new Thread(){
@Override
public void run(){
try {
synchronized(this){
wait(5000);
}
}
catch(InterruptedException ex){
}
finish();
Intent intent = new Intent();
intent.setClass(sPlashScreen, MainActivity.class);
startActivity(intent);
stop();
}
};
mSplashThread.start();
}
@Override
public boolean onTouchEvent(MotionEvent evt)
{
if(evt.getAction() == MotionEvent.ACTION_DOWN)
{
synchronized(mSplashThread){
mSplashThread.notifyAll();
}
}
return true;
}
}
It’s time now to make a first run. And we have the splash screen waiting for 5 seconds. Doesn’t look good, just two black screens, one after another.
A Little Beautification
First, let’s make the splash screen transparent. In appfolder/res/values, add new Android XML file styles.xml and add to it a transparent theme:
<resources>
<style name="Theme.Transparent" parent="android:Theme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
</resources>
Here are some explanations: as you can see, the style’s parent is android:Theme
so we could apply it to our activity. And as you can see, the attribute's names are clear and you can understand what they mean.
Next, we’ll apply this theme to our splash. In the manifest file for the splash activity, set a "theme
" attribute to the just created theme:
<activity
android:name="SplashScreen"
android:theme="@style/Theme.Transparent"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"></action>
<category android:name="android.intent.category.LAUNCHER"></category>
</intent-filter>
</activity>
Let’s suppose we’re developing a game application. And gamers don’t like when something distracts them from the game process. Most of them prefer fullscreen mode. So, set the fullscreen theme for the main activity:
<activity android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
Run it. Looks better. Now we’ll make it fade-in and fade-out. Create in appfolder/res folder new folder "anim" and add to it two Android XML files – appear.xml and disappear.xml. They will be alpha animations.
Appear.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:interpolator="@android:anim/accelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="800"
/>
</set>
Disappear.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:interpolator="@android:anim/decelerate_interpolator"
android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="800"
/>
</set>
In these animations, they just change the alpha channel of an object from fromAlpha
value to toAlpha
value for a given period of time. Now add new style in styles.xml:
<style name="Animations" parent="@android:Animation" />
<style name="Animations.SplashScreen">
<item name="android:windowEnterAnimation">@anim/appear</item>
<item name="android:windowExitAnimation">@anim/disappear</item>
</style>
</style>
So, on the window, enter the “appear
” animation will be performed and on the window exit the “disappear
” animation will be performed. Add this style to Theme.Transparent
theme:
<style name="Theme.Transparent" parent="android:Theme">
………
<item name="android:windowAnimationStyle">@style/Animations.SplashScreen</item></style>
Ok, it’s time to run it again. Now it looks nice. And more…
Don’t Shoot at a Programmer, He Draws As He Can…
Let’s create an animated splash screen. As an artist, I’m not very good so I used Gimp’s Script-Fu to generate a set of frames for animations. First, remove android:src
attribute in splash.xml. Then, in the drawable folder, create flag.xml:
="1.0"="utf-8"
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/flaganim"
android:oneshot="false"
>
<item android:drawable="@drawable/f03" android:duration="100" />
<item android:drawable="@drawable/f04" android:duration="100" />
<item android:drawable="@drawable/f05" android:duration="100" />
<item android:drawable="@drawable/f06" android:duration="100" />
<item android:drawable="@drawable/f07" android:duration="100" />
<item android:drawable="@drawable/f08" android:duration="100" />
<item android:drawable="@drawable/f09" android:duration="100" />
<item android:drawable="@drawable/f10" android:duration="100" />
</animation-list>
Here is a set of frames and “oneshot
” attribute says to loop them. To run animation, we need to change the splash screen class code. To the onCreate
method, add the following:
final ImageView splashImageView = (ImageView) findViewById(R.id.SplashImageView);
splashImageView.setBackgroundResource(R.drawable.flag);
final AnimationDrawable frameAnimation =
(AnimationDrawable)splashImageView.getBackground();
We've set the animation for the splash, but here’s a little problem. We can’t start it from the onCreate
method. The animation must be started from GUI thread. For this, we’ll use a “post
” method of the ImageView
class. It will add our runnable to a message queue and when GUI thread will be available, it will start it:
splashImageView.post(new Runnable(){
@Override
public void run() {
frameAnimation.start();
}
});
And here we are:
That’s all. Have fun with Android programming.
Thanks!
History
- 29th September, 2010: Initial post