Splash Fade, Activity Animations, overridePendingTransition
(In the interests of consistency and clarity I'm using plusminus' tutorial format.)
What you learn: You will learn how to create a splash screen activity that fades into the next activity. (Android 2.0 only).
Difficulty: 1.5 of 5
What it will look like: Please note, the emulator runs very slowly compared to the actual Droid, so the video here is quite jerky, but should give you a general idea. Unfortunately, I can't get video capture of the Droid desktop.
[youtube]http://youtube.com/watch?v=yplvGIuLE5M[/youtube]
Tested on Android 2.0, emulator and Droid handset. Not available for previous Android versions.
Description:
In this tutorial we will create two activities, a splash screen activity and a main activity. We will use a fade transition between the two activities using the overridePendingTransition() API introduced in Android 2.0. The splash activity will fade out as the main activity fades in. We will also set the splash screen activity so that it does not reappear when the user presses the back button.
overridePendingTransition() was introduced in Android 2.0 expressly for handling animated transitions between activities. This allows us to keep the modular coding style of activities, and still be able to animate their transitions. Prior to the introduction of overridePendingTransition(), animated transitions had to be handled manually, or views used in place of activities.
0.) Since this tutorial includes material only found in Android 2.0, you will need an Eclipse project targeting the Android 2.0 platform. In particular this means you will have multiple res/drawable folders.
1.) We need some layout resources:
In your res/layout folder, create a file named splash.xml, and add:
Using xml Syntax Highlighting
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <ImageView
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:scaleType="fitXY"
- android:src="@drawable/splash"
- />
- </LinearLayout>
Parsed in 0.002 seconds, using GeSHi 1.0.8.4
In the same folder, edit main.xml. Replace the current contents with:
Using xml Syntax Highlighting
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <ImageView
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:scaleType="fitXY"
- android:src="@drawable/main"
- />
- </LinearLayout>
Parsed in 0.002 seconds, using GeSHi 1.0.8.4
Both of these are simple ImageViews; I've used them because they make a nice transition, obviously you can use whatever is appropriate. The only noteworthy item is scaleType set to fitXY. fitXY scales the chosen bitmap to fit the view.
In your res/drawable-xxxx folders add two .png images (of your choice), named splash.png and main.png. (I chose title_bg_hori.png and pressed_application_background_static.png from the SDK and just renamed them for clarity).
2.) We need some animation resources:
In your res/anim folder (create an anim folder in /res if it's not already there), create a file named splashfadeout.xml, and add:
Using xml Syntax Highlighting
- <?xml version="1.0" encoding="utf-8"?>
- <alpha xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/decelerate_interpolator"
- android:zAdjustment="top"
- android:fromAlpha="1.0"
- android:toAlpha="0.0"
- android:duration="1000" />
Parsed in 0.001 seconds, using GeSHi 1.0.8.4
In the same directory, create a file name mainfadein.xml, and add:
Using xml Syntax Highlighting
- <?xml version="1.0" encoding="utf-8"?>
- <alpha xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/accelerate_interpolator"
- android:fromAlpha="0.0"
- android:toAlpha="1.0"
- android:duration="1000" />
Parsed in 0.001 seconds, using GeSHi 1.0.8.4
These are simple animations that will fade out/in an image over time. The interpolators control how the fade occurs. For example, we are using a decelerate_interpolator for our splash fade out, so our splash will fade quickly at first, then slow down as it approaches its final fade value (in this case 0, to indicate fully faded, or transparent). Similarly for our main image fade in, the accelerate_interpolator will cause our fade in to start slowly and speed up as time goes on. In both cases, our duration is 1 second; duration is specified in milliseconds. We'll talk about the zAdjustment attribute later.
For this demo, I've used duration values significantly longer than recommended for a commercial application. This was done so the transitions could be seen, even on a slow emulator. For real world activities, transition times (the duration values in the anim .xmls) should be set to one of the Android preconfigured values, such as:
- Code: Select all
android:duration="@android:integer/config_longAnimTime"
config_longAnimTime is just slightly less than a half second, and is long enough for most purposes. Of course, this is just a suggestion.
3.) Make a splash activity, SplashScreen.java. I won't cover the basics of creating the splash activity, as plusminus has done a nice job here. A full listing of SplashScreen.java appears at the end of this tutorial.
Our splash activity will display the splash layout (described earlier) using setContentView() for SPLASH_DISPLAY_TIME milliseconds (e.g., 2000 milliseconds = 2 seconds). After SPLASH_DISPLAY_TIME milliseconds, we will:
- Create an intent for our main activity and start it.
- Complete our current splash activity and clean it up so that the user cant go back to it.
- Apply our animation transitions so that our splash activity fades out as our main activity fades in.
Using java Syntax Highlighting
- /* Create an intent that will start the main activity. */
- Intent mainIntent = new Intent(SplashScreen.this, MainApp.class);
- SplashScreen.this.startActivity(mainIntent);
- /* Finish splash activity so user cant go back to it. */
- SplashScreen.this.finish();
- /* Apply our splash exit (fade out) and main
- entry (fade in) animation transitions. */
- overridePendingTransition(R.anim.mainfadein, R.anim.splashfadeout);
Parsed in 0.033 seconds, using GeSHi 1.0.8.4
overridePendingTransition() handles our animated transition between the splash and main activities. Two animation resources need to be supplied, one for the entry of the new activity (ours is R.anim.mainfadein), and one for the exit of the old activity (ours is R.anim.splashfadeout).
The two animations will occur at the same time. This is one reason why I chose the interpolators the way I did (see step 2). The animations occur simultaneously, and these blend into each other nicely. The zAdjustment attribute can be used to keep the exiting activity's animation on top, as was done here. If you don't do this, the default is for the entering activity's animation to be on top, and your splash fade out will happen underneath your main fade in, so you won't see it.
You can use 0 for either animation if you don't want an animated transition but beware: if for some reason you want an animation for the entering activity, but not for the exiting activity, you should create a placeholder animation that does nothing (in our example, set the fromAlpha and toAlpha values to 1.0 in splashfadeout.xml). This will keep the exiting activity around long enough for the entering activity's animation to overlay properly. Otherwise you will see a momentary blank screen instead of a smooth transition. The ApiDemos sample in the SDK has more on this in the Apps/Activity/Animation subsample, and an example of how to create a placeholder 'hold' xml, as just described.
For more on animation in general see here.
4.) Make a main activity MainApp.java. This is just a simple placeholder activity, so our splash activity has somewhere to go. A full listing of MainApp.java appears at the end of this tutorial, but the heart is:
Using java Syntax Highlighting
- public class MainApp extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- }
Parsed in 0.031 seconds, using GeSHi 1.0.8.4
5.) The last thing we need before we test is to set up our application's attributes, activities and intent filters. Edit AndroidManifest.xml and replace the current <application> tag with:
Using xml Syntax Highlighting
- <application android:icon="@drawable/icon" android:label="@string/app_name"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
- <activity android:name=".SplashScreen" android:screenOrientation="landscape">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <activity android:name=".MainApp" android:screenOrientation="landscape">
- </activity>
- </application>
Parsed in 0.002 seconds, using GeSHi 1.0.8.4
We've made our application be landscape only, fullscreen and with no titlebar. Our application has our two activities, SplashScreen and MainApp.
Caveats:
-Users can override animation transitions for windows (Settings->Sound & display->Animation), but not for views. If you feel that a lack of animated transitions would negatively impact your application, you may wish to consider an alternative to overridePendingTransition(), such as doing transitions only in views (which can not be overridden by the user).
-If you need to go back to previous activities using the back button, you will not have animation transitions using overridePendingTransition(). For activities which only occur once and are then removed from the history stack, such as splash activities, overridePendingTransition() is perfect. If you need animations back to your previous activities, you might consider other alternatives.
Takeaways:
- Use overridePendingTransition() for animated transitions between activities; this is particularly suitable for once-and-done type activities, such as splash screens.
- Realize that the animations used by overridePendingTransition() occur simultaneously.
- Use the zAdjustment attribute to set up z order for your entering/exiting activities.
- Understand that users can override animation settings if they prefer no animations; such an override may be unsuitable for your application.
"/src/your_package_structure/SplashScreen.java"
Using java Syntax Highlighting
- package com.example.splashtest;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.Handler;
- public class SplashScreen extends Activity {
- private static final int SPLASH_DISPLAY_TIME = 2000; /* 2 seconds */
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.splash);
- /* Create a new handler with which to start the main activity
- and close this splash activity after SPLASH_DISPLAY_TIME has
- elapsed. */
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- /* Create an intent that will start the main activity. */
- Intent mainIntent = new Intent(SplashScreen.this,
- MainApp.class);
- SplashScreen.this.startActivity(mainIntent);
- /* Finish splash activity so user cant go back to it. */
- SplashScreen.this.finish();
- /* Apply our splash exit (fade out) and main
- entry (fade in) animation transitions. */
- overridePendingTransition(R.anim.mainfadein,
- R.anim.splashfadeout);
- }
- }, SPLASH_DISPLAY_TIME);
- }
- }
Parsed in 0.038 seconds, using GeSHi 1.0.8.4
"/src/your_package_structure/MainApp.java"
Using java Syntax Highlighting
- package com.example.splashtest;
- import android.app.Activity;
- import android.os.Bundle;
- public class MainApp extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- }
Parsed in 0.036 seconds, using GeSHi 1.0.8.4
Hope this helps!
XCaf




