User Tools

Site Tools


android-labs-s14:class-02

Class 02

In this class, we'll be learning about what is Activity and its life cycle. We'll see how we can use intents to launch activities. Apart from that, we'll take a glance over Android Manifest file, and we will also look into some basic UI components (Relative Layout, Linear Layout and GridView) to get you started.

Activity

  • Application component that provides a screen with which users can interact in order to do something.
  • Can be full-screen, or a floating window, or even embedded inside another activity.
  • Can start another activity in order to perform different actions.

Activity Lifecycle

(Figure source: developer.android.com Link)

The square rectangles in the above diagram represent callback methods you can implement to perform operations when the Activity moves between states. The colored ovals are major states the Activity can be in.

Activity States

State Description
Running/Resumed Activity is visible and interacts with the user.
Paused Activity is still visible but partially obscured, instance is running but might be killed by the system.
Stopped Activity is not visible, instance is running but might be killed by the system.
Destroyed Activity has been terminated by the system of by a call to its finish() method.

(Figure source: developer.android.com Link). The above figure shows an Android application lifecycle depicting different Activity states.

Lifecycle Methods

Method Purpose
onCreate() Called when the activity is first created
onStart() Called when the activity becomes visible to the user
onResume() Called when the activity starts interacting with the user
onPause() Called when the current activity is being paused and the previous activity is being resumed
onStop() Called when the activity is no longer visible to the user
onDestroy() Called before the activity is destroyed by the system (either manually or by the system to conserve memory)
onRestart() Called when the activity has been stopped and is restarting again

Intents

  • Mostly used for launching activities (even of other applications)
  • Also help communicating with a background service

AndroidManifest.xml

  • Holds information the system must have, before it can run any of the application's code.
  • Names the Java package for the application.
  • Describes application components - like activities and services.
  • Declares which permissions the application must have in order to access protected parts of the API and interact with other applications.
  • Declares the minimum level of the Android API that the application requires.
  • Following is a sample AndroidManifest.xml file:
SampleAndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.imageviewer"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
 
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.imageviewer.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
        <!-- ImageGrid Activity -->
        <activity
		android:name="com.example.imageviewer.ImageGridActivity"
		android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
 
    </application>
 
</manifest>

Layouts

(Figures in this section are drawn from www.androidhive.info)

LinearLayout

  • LinearLayout Sketch and Output

RelativeLayout

  • RelativeLayout Sketch and Output


GridView

  • A two-dimensional, scrollable grid

[Figure source: developer.android.com]

Examples

Adapter

  • Bridge between an AdapterView (ListView, GridView, etc.) and the underlying data for that view.
  • Provides access to the data items.
  • Responsible for making a View for each item in the data set.
  • Key method: getView() - The method gets a View that displays the data at the specified position in the grid.
  • Video explaining GridView, ListView and Adapters: Google IO 2010 - World of List View

Building an "Image Viewer" App

Let's build a simple application which lets you:

  • see a collection of photos
  • access photos stored in the (pre-installed) Gallery Application

So, in this app, we'll be having two screens:

  1. Main Screen (MainActivity)
  2. Image Grid Screen (ImageGridActivity)

Step 01 : Create an Android Application Project

  • Follow the same steps as mentioned in Class 01 for Hello World App, but this time you can rename your app to something like 'ImageViewer'.

Step 02 : Add three buttons to MainActivity

  • Go to 'res/layout/activity_main.xml', and replace its code with the following code snippet:
activity_main.xml
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
 
    <!-- Application Title Text Label-->
    <TextView
        android:id="@+id/text_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="UW Image Viewer"
        android:textSize="22sp"
        android:textStyle="bold" />
 
    <!-- Button to view the grid of UW Images -->
    <Button
        android:id="@+id/button_uwimages"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/text_title"
        android:layout_centerHorizontal="true"
        android:onClick="onButtonClick"
        android:text="UW Images" />
 
    <!-- Button to open already installed Gallery App -->
    <Button
        android:id="@+id/button_gallery"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/button_uwimages"
        android:layout_centerHorizontal="true"
        android:onClick="onButtonClick"
        android:text="Open Gallery Application" />
 
    <!-- Button to define some application preferences -->
    <Button
        android:id="@+id/button_settings"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/button_gallery"
        android:layout_centerHorizontal="true"
        android:onClick="onButtonClick"
        android:text="Settings" />
 
</RelativeLayout>
  • Now, your app should look like following:

Things to notice:

  • The context of this xml is 'MainActivity'.
  • We are using RelativeLayout to layout the Buttons and TextView relative to eachother.
  • All views and viewgroups are required to define 'layout_width' and 'layout_height' properties.
  • Using 'id' for a resource is optional.
  • '@+id' is used to declare the resource, and '@id' to refer to already declared resource.
  • 'onButtonClick' is a user-defined method name, which should have its implementation in 'MainActivity.java' file.
  • Lets try opening Gallery App with the click on 'Open Gallery' button on the Main Screen. For that, we'll implement onButtonClick method in MainActivity.java. So, let's add following code block to the 'MainActivity' class.
	/**
	 * Callback method for clicks on the buttons in Main Screen.
	 * @param v		View clicked
	 */
	public void onButtonClick(View v)
	{
		switch(v.getId())
		{
 
		case R.id.button_gallery:
 
			Intent galleryIntent = new Intent(Intent.ACTION_PICK, 
					android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
			startActivityForResult(galleryIntent, 0);		
 
			break;
 
		default:
		}
	}
  • Now, clicking on 'Open Gallery Button' should bring up something like the figure below:

Step 04 : Add another activity class (say, 'ImageGridActivity.java') to the Project

  • Follow the steps below to create a new class:

  • Add 'onCreate' method to 'ImageGridActivity' class:
ImageGridActivity.java
package com.example.imageviewer;
 
import android.app.Activity;
import android.os.Bundle;
 
public class ImageGridActivity extends Activity
{
	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_imagegrid);
	}
}
  • Now, similarly, go to 'res/layout' folder, and add a new 'Android XML File'. Lets call it 'activity_imagegrid.xml'.

  • Now replace the xml in 'activity_imagegrid.xml' by the following xml snippet:
activity_imagegrid.xml
<?xml version="1.0" encoding="utf-8"?>
 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
 
    <!-- ImageGrid Screen Title -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="UW Madison Images"
        android:textSize="20sp" />
 
    <!-- Although not required in this case, but I just wanted to demonstrate its use -->
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    	android:fillViewport="true" >
 
	    <!-- Grid View showing image thumbnails -->
		<GridView
			android:id="@+id/grid_view"
			android:layout_width="match_parent"
			android:layout_height="match_parent"
			android:padding="10dip"
			android:numColumns="2"
			android:stretchMode="columnWidth"
			android:verticalSpacing="20dp"
			android:horizontalSpacing="20dp"
			android:gravity="center" />
 
    </ScrollView>
 
</LinearLayout>

Things to notice:

  • We have added a TextView (to show Activity title), and a GridView (to show thumbnail of images)
  • We have used LinearLayout to layout the UI Views vertically.

Step 05 : Launch 'ImageGridActivity' by tapping on 'UW Images' Button on Main Screen

  • Replace 'onButtonClick' method in MainActivity.java by the following code snippet.
	/**
	 * Callback method for clicks on the buttons in Main Screen.
	 * @param v		View clicked
	 */
	public void onButtonClick(View v)
	{
		switch(v.getId())
		{
		case R.id.button_uwimages:
 
			// Create new intent
			Intent i = new Intent(MainActivity.this, ImageGridActivity.class);
			startActivity(i);
 
			break;
 
		case R.id.button_gallery:
 
			// Open pre-installed Gallery Application
			Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
			startActivityForResult(galleryIntent, 0);		
 
			break;
 
		case R.id.button_settings:
 
			// Lets just show toast for now.
			Toast.makeText(this, "Will add Preferences later!", Toast.LENGTH_LONG).show();
			break;
 
		default:
		}
	}

Things to notice:

  • As a click callback for 'UW Images' button, we've added an Intent to launch ImageGridActivity.
  • As a click callback for 'Settings' button, we've added a simple toast message.

Now, after clicking the 'UWImages' Button, the app should crash. And, you should see the following error dialog:

Step 06 : Fixing AndroidManifest.xml

  • To find what is the issue, let's take a look at the logcat. Go to Logcat window in Eclipse, and you should see the error as shown below:

  • To fix it, we need to tell the application about the presence of ImageGridActivity. And, we can do that by adding the following snippet to AndroidManifest.xml inside <application> tag.
        <!-- ImageGrid Activity -->
        <activity
		android:name="com.example.imageviewer.ImageGridActivity"
		android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
  • Now, clicking on 'UW Images' button, you'll see ImageGrid Screen as following image:

Step07 : Linking Images to GridView

  • Create a folder called 'drawable' inside 'res'. This will act as a default folder of images for devices with different resolutions.
  • Click on this link to download all_images.zip file. Extract all the images in this directory and copy them to 'drawable' folder.
  • Add a new class (lets call it 'ImageAdapter.java') to the Project. Replace the code in the file by the code below:
ImageAdapter.java
package com.example.imageviewer;
 
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
 
public class ImageAdapter extends BaseAdapter
{
 
	private Context mContext;
 
	public ImageAdapter(Context c) // Constructor
	{
		mContext = c;
	}
 
	public Integer[] mThumbs = { R.drawable.pic0_thumb, R.drawable.pic1_thumb,
			R.drawable.pic2_thumb, R.drawable.pic3_thumb, R.drawable.pic4_thumb,
			R.drawable.pic5_thumb, R.drawable.pic6_thumb, R.drawable.pic7_thumb,
			R.drawable.pic8_thumb, R.drawable.pic9_thumb, R.drawable.pic10_thumb,
			R.drawable.pic11_thumb, R.drawable.pic12_thumb, R.drawable.pic13_thumb,
			R.drawable.pic14_thumb, R.drawable.pic15_thumb, R.drawable.pic16_thumb,
			R.drawable.pic17_thumb, R.drawable.pic18_thumb, R.drawable.pic19_thumb,
			R.drawable.pic20_thumb, R.drawable.pic21_thumb, R.drawable.pic22_thumb,
			R.drawable.pic23_thumb, R.drawable.pic24_thumb, R.drawable.pic25_thumb,
			R.drawable.pic26_thumb, R.drawable.pic27_thumb, R.drawable.pic28_thumb,
			R.drawable.pic29_thumb, R.drawable.pic30_thumb, R.drawable.pic31_thumb,
			R.drawable.pic32_thumb, R.drawable.pic33_thumb, R.drawable.pic34_thumb,
			R.drawable.pic35_thumb, R.drawable.pic36_thumb, R.drawable.pic37_thumb,
			R.drawable.pic38_thumb, R.drawable.pic39_thumb };
 
	@Override
	public int getCount()
	{
		return mThumbs.length;
	}
 
	@Override
	public Object getItem(int position)
	{
		return mThumbs[position];
	}
 
	@Override
	public long getItemId(int position)
	{
		return position;
	}
 
	@Override
	public View getView(int position, View convertView, ViewGroup parent)
	{
		ImageView imageView;
		if (convertView == null)
		// Recycled View
		{
			imageView = new ImageView(mContext);
			imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
			imageView.setLayoutParams(new GridView.LayoutParams(220, 220));
		} else
		// Re-use the view
		{
			imageView = (ImageView) convertView;
		}
		imageView.setImageResource(mThumbs[position]);
		return imageView;
	}
 
}
  • Now, we need to fill in the images from the Adapter to the GridView we described in 'activity_imagegrid.xml'. To do that, lets add following code snippet to 'onCreate' method on ImageGridActivity:
		// Get GridView from xml
		GridView gridView = (GridView) findViewById(R.id.grid_view);
 
		// Set Adapter for GridView
		gridView.setAdapter(new ImageAdapter(this));
  • Now, clicking on 'UW Images' Button should bring up the images stored in 'drawable' folder:

android-labs-s14/class-02.txt · Last modified: 2014/01/29 16:04 by prakhar