Lab 1.2 – The Splash Activity

Lab time: 45 min.

To start this lab you need to have created the The Cow Goes BOO project from the previous lab. If you haven’t done this yet download the sources for lab 1.1. Unzip this file to some location, create a new Android project in Eclipse and select “Create project from existing sources”. Browse to the folder you unzipped the project into and then to the folder lab1.1. Everything in the new Android Project dialog should be filled in automatically. Change the project name to “The Cow Goes BOO” and press Finish.

Goal of this lab

This is what we’ll create in this lab

New concepts in this lab

  • Activities
  • Layouts
  • Views and widgets
  • Resources
  • Animations
  • Changing the application icon
If you are comfortable with all these concepts you can skip this lab and continue with Lab 1.3

Getting started

Ok, let’s start. If all’s well you should have a project structure similar to this

lab1.2-project-structure-after-import

We have to start somewhere so let’s open up the first file in the project, SplashActivity.java

package cow.boo;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class SplashActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_splash);
	}

}

Activites

Our SplashActivity extends the Activity class. An activity usually is a full Android screen that a user sees or interacts with. The onCreate is what we call a life cycle callback method and this gives you a hook where you can initialize your activity when the Android system decides it is time to show your activity to the user. The Activity life cycle is very important and deserves good understanding when you are planning to do more Android development after this workshop.

Note: If you don’t have an internet connection and you have installed the documentation package you can find the same page on the Activity class and life cycle in the directory you installed your Android SDK in. Open a browser and open the following html-page <android-sdk-install-dir>/docs/reference/android/app/Activity.html

The call to setContentView() fills in the contents of the activity’s window with an Android view (we’ll come to that later). R.layout.activity_splash is a resource identifier that refers to the activity_splash.xml file in the res/layout directory. activity_splash.xml declares the user interface in XML. At runtime, Android parses and instantiates (inflates) the resource defined there and sets it as the view for the current activity. Let’s open up the activity_splash.xml file.

Layouts

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    
</LinearLayout>

The LinearLayout is a container for one or more child objects and describes a certain behavior to position them on the screen within the rectangle of the parent object. Here is a list of the most common layouts provided by Android:

  • FrameLayout: Arranges its children so they all start at the top left of the screen. This is used for tabbed views and image switchers.
  • LinearLayout: Arranges its children in a single column or row. This is the most common layout you will use.
  • RelativeLayout: Arranges its children in relation to each other or to the parent. Another layout you will use a lot, but which is not covered in this lab.
  • TableLayout: Arranges its children in rows and columns, similar to an HTML table.

Some parameters are common to all layouts:

  • xmlns:android="http://schemas.android.com/apk/res/android"Defines the XML namespace for Android. You should define this once, on the first XML tag in the file.
  • android:layout_width="fill_parent", android:layout_height="fill_parent"Takes up the entire width and height of the parent (in this case, the window). Possible values are fill_parent and wrap_content.

Update: As of API level 8 the fill_parent attribute value has been deprecated. It is superseeded by the match_parent value as this better describes the behavior. However, the Eclipse ADT-plugin still uses fill_parent since it still gives the same result and will ensure backwards compatibility. We will continue to use fill_parent in this workshop as well.

Views / Widgets

Inside the <LinearLayout> tag you’ll find one child widget:

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello" />

This defines a simple text label with the text “@string/hello”. This is an identifier of a tag with name hello which lives in the string
resource file res/values/string.xml.

Let’s replace the text “@string/hello” with the resource identifier for the application name (which also is defined in the string.xmlfile).

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/app_name" />

You can remove the tag with name “hello” in the string.xml file. We don’t need it anymore.

Now, let’s add the following splash icon the the layout.

Right-click this image and save it in the folder res/drawable-hdpi. Oh, before you paste the image open the R.java file in the gen-folder in the cow.boo package. Got it open? Ok, now paste the image in the res/drawable-hdpi folder, come back to Eclipse and refresh the project (or press F5) and see what happens to the drawable static variable. (Don’t read on! Paste the file!).

Since you have the R.java file in front of you a little bit more about Android resources.

Resources

A resource is a localized text string, bitmap, video, soundbit or other small piece of noncode information that your program needs. At build time all your resources get compiled into your application. This is useful for internationalization and for supporting multiple device types.

You will create and store your resources in the res directory inside your project. The Android resource compiler (aapt) processes resources according to which subfolder they are in and the format of the file. For example, PNG and JPG format bitmaps should go in a directory starting with res/drawable, and XML files that describe screen layouts should go in a directory starting with res/layout. You can add suffixes for particular languages, screen orientations, pixel densities, and more.

The resource compiler compresses and packs your resources and then generates a class named R that contains identifiers you use to reference those resources in your program. This is a little different from standard Java resources, which are referenced by key strings. Doing it this way allows Android to make sure all your references are valid and saves space by not having to store all those resource keys. Eclipse uses a similar method to store and reference the resources in Eclipse plug-ins.

Ok, we want to display this image in the splash activity. To do this we can use the ImageView widget.

Let’s add the ImageView before the TextView widget in main.xml

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/splash_icon"
    />

You can of course copy and paste this code, but typing it yourself and using ctrl-space (autocomplete) a lot will give you a little bit more insight what attributes can be added and what values are valid. Try it…

Nice nice. Let’s tweak the various attributes of the layout and views to make this look a little bit better.

  • Let’s move the image a bit down by adding a padding to the top of the linear layout of 100dip.
  • Move the image to the middle of the screen by changing the the layout_width of the ImageView to fill_parent. Keep the layout_height at wrap_content so the scale stays in tact.
  • Change the text size to 24dip in the TextView
  • Hmm… the text is still aligned to the left. Set the gravity attribute to center_horizontal
  • Add a padding of 40dip to the top of the TextView
  • You can play around with the other text attributes like textColor, shadowColor, shadowRadius, etc.

Animations

Finally, the animation bit. We already have an id of the ImageView object.

  • Open the SplashActivity class. Now you can reference the ImageView object with the following code (We want to start the animation directly after the Activity has been created, so right after the call to setContentView is fine.):
	ImageView splashIcon = (ImageView) findViewById(R.id.splash_icon);

The View object defines a startAnimation method which takes a Animation object. We can load an animation by calling the static loadAnimation method of the AnimationUtils class. The first argument is a Context, which conveniently is implemented by the Activity class, so we can pass this as the first argument. The second argument is an int reference to an animation resource. We can create our own custom animation (which we’ll do in a minute) but Android itself has its own resource class in the android package. There are a couple of standard animations which you can use.

  1. Create an Animation object by using the loadAnimation method of the AnimationUtils class. Try passing in the following ids android.R.anim.fade_in or android.R.anim.slide_in_left.
  2. Set the duration of the animation
  3. Call the startAnimation method on the splashIcon object using the Animation instance you created in step 1.
  4. Run your application.

Custom animations

You can do three types of animation in Android.

  1. OpenGL (3D) obviously, this of course is what OpenGL is all about.
  2. Tween Animation Creates an animation by performing a series of transformations on a single image. An Animation.
  3. Frame Animation Creates an animation by showing a sequence of images in order. An AnimationDrawable.

We’ll do Tween Animation in this workshop, an animation defined in XML that performs transitions such as rotating, fading, moving, and stretching on a graphic. The file must have a single root element: either an <alpha>, <scale>, <translate>, <rotate>, or <set> element that holds a group (or groups) of other animation elements (even nested <set> elements). The custom animation XML file should be placed in the res/anim and like any other resource, once you’ve copied it in the res directory an id is created in the R.java file. You can reference your animation by passing its id to the loadAnimation method of the AnimationUtils class.

Without further explanation we’ll present you with a custom_anim.xml file which defines a set of animations.

Create an anim directory in the res-folder and create the custom_anim.xml file with the following contents:

<?xml version="1.0" encoding="utf-8" ?>
<set
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <rotate
        android:fromDegrees="0"
        android:toDegrees="2160"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="4000" />
    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:duration="2000">
    </alpha>
    <scale
        android:pivotX="50%"
        android:pivotY="50%"
        android:fromXScale=".1"
        android:fromYScale=".1"
        android:toXScale="1.0"
        android:toYScale="1.0"
        android:duration="3000" />
</set>
For further explanation see the animation resource section in the Dev guide

If all’s well the code below the call to setContentView should look something like this

    Animation customAnimation = AnimationUtils.loadAnimation(this, R.anim.custom_anim);
    ImageView splashIcon = (ImageView) findViewById(R.id.splash_icon);
    splashIcon.startAnimation(customAnimation);

That’s it!

Take your application for a spin (if you haven’t done so already ;-) )

Custom app launcher icon

Finally, the custom icon in the application launcher. When you create an Android project, and you don’t create a custom launch icon at project setup, you are presented with the default app launcher icon:

In fact, there are four icons, of extra high, high, medium and low quality. They reside in the res/drawable-xhdpi, res/drawable-hdpi, res/drawable-mdpi and res/drawable-ldpi directories respectively.

Save the images below into the appropriate directories.
  
Run the application again and verify the icon appears in the application launcher.

Optional exercises

  • Try to add the following background to the splash screen (big hints: attribute and relative layout).
  • Add another TextView to the layout containing some version information and a short description what this app is all about.

This lab is done! Great job! Tick it off and go to Lab 1.3