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