Events

Android Event Handling Example

Events represents a response to user’s interaction with input controls, such as press of a button or touch of the screen. Android framework places each occurring Event into a queue, which is based on FIFO (first-in first-out) logic. When an Event happens an Event Listener, which is involved with the View object, should be registered. Then, the registered Event Listener should implement a corresponding callback method (Event Handler), in order to handle the Event.

 
 
 
 

Some of the most used Event Handlers with the respective Event Listeners are:

  • onClick()onClickListener(): for clicking or focusing upon a View component.
  • onLongClick()onLongClickListener(): for clicking or holding or focusing upon a View component, for more than one second.
  • onTouch()onTouchListener(): performing a touch action, including motion gesture on the screen.
  • OnKey()onKeyListener(): presses or releases a hardware key on the device.
  • onFocusChange()onFocusChangeListener(): for navigation onto or away from an item.

In this example we will indicate different ways of onClickListener registration and the pros and cons of each situation. The different approaches that we will show are:

  • Implement the Event Listener interface into the Activity class
  • Using an anonymous inner Event Listener class
  • Using a separate Event Listener class
  • Declare it into the layout XML file.

For this tutorial, we will use the following tools in a Windows 64-bit platform:

  1. JDK 1.7
  2. Eclipse 4.2 Juno
  3. Android SDK 4.4

1. Create a New Android Application Project

Open Eclipse IDE and go to File → New → Project → Android Application Project.

Specify the name of the application, the project and the package and then press Next button.

EventHandleTestProj1

In the next window, the “Create Activity” option should be checked. The new created activity will be the main activity of your project. Then click Next.

EventHandleTestProj2

In “Configure Launcher Icon” window you should choose the icon you want to have in your app. We will use the default icon of android, so click Next.

createProject3!

Choose the “Blank Activity” option and press Next.

createProject4!

You have to specify a name for the new Activity and a name for the layout description of your app. The .xml file for the layout will automatically be created in the res/layout folder. Finally, press Finish.

createProject5!

Now, you can see the final structure of the created project in the image below.

EventHandleTestStructure

2. Create the layouts

We will create two different layouts because we will make two Activities, in order to show the different ways for Event Listener.

The first layout will be the one that has already been created. So open res/layout/activity_main.xml, go to the xml tab and paste the following.

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" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text"
        android:layout_marginBottom="20dp"
        android:text="@string/text_msg"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    
    <Button 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/buttonMain"
        android:layout_below="@id/text"
        android:text="@string/text_btnMain" />

     <Button
         android:id="@+id/nextBtn"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentRight="true"
         android:layout_below="@+id/buttonMain"
         android:layout_marginTop="100dp"
         android:text="@string/text_next" />

</RelativeLayout>

The other layout will be used for another Activity class. Right click on res/layout directory → New → Android XML File, in order to create the XML layout file. Then specify the name and select LinearLayout as root element, as shown in the next picture. Then click Finish.

EventHandleTest_listener_view

Now open res/layout/listener_view.xml file to the xml tab and paste the code below.

listener_view.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" >
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/text2"
        android:layout_marginBottom="20dp"
        android:text="@string/text2_msg"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    
    <Button 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/button1"
        android:text="@string/text_btn1" />
    
    <Button 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:id="@+id/button2"
        android:onClick="clickButton2"
        android:text="@string/text_btn2" />
    
    <Button 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:id="@+id/button3"
        android:text="@string/text_btn3" />
    

</LinearLayout>

As you can notice in the highlighted line, we declare the handler method that will be enabled when the user is going to press the button2. The other Buttons are used for the other approaches of Event Listener.

Also, we should define the appropriate strings in the strings.xml file, so open res/values/strings.xml file, go to the respective xml tab and paste the following code.

strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">EventHandleTest</string>
    <string name="action_settings">Settings</string>
    <string name="text_msg">Listener Interface or Next...</string>
    <string name="text2_msg">Select a way for Event Handling</string>
    <string name="text_btn1">Inner Listener Class Button</string>
    <string name="text_btn2">onClick Button</string>
    <string name="text_btnMain">Listener Interface Button</string>
    <string name="text_btn3">Listener in Separate Class Button</string>
    <string name="text_next">Go to next Activity</string>

</resources>

3. Code the Event Listener Interface Activity

At this point we show the situation where the Activity class implements an Event Listener interface. This is the easiest way of the other approaches and it is recommended for a single control of that Listener. It has a poor scale for multiple controls, because Listener can not take arguments. Also a big range of multiple controls requires a further programming, in order to check which control fires the Event.

As we mentioned before, we will use onClickListener as an example of Event Listener approaches.

Open src/com.javacodegeeks.android.eventhandletest/MainActivity.java and paste the following code.

MainActivity.java:

package com.javacodegeeks.android.eventhandletest;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

	private TextView text;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		text = (TextView) findViewById(R.id.text);
		
		Button listenerBtn = (Button) findViewById(R.id.buttonMain);
		listenerBtn.setOnClickListener(this);
		
		Button nextBtn = (Button) findViewById(R.id.nextBtn);
		nextBtn.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.buttonMain:
			text.setText("Listener implementation in the Activity!");
			Toast.makeText(this, "Implements onClickListener", 
					Toast.LENGTH_SHORT).show();
			break;

		case R.id.nextBtn:
			try{
				Intent intent = new Intent(this, ListenerActivity.class);
				startActivity(intent);
			}catch(Exception ex) {
				ex.printStackTrace();
			}
			break;
			
		default:
			break;
		}
	}

}

As you can see in the code above, the MainActivity extends Activity as well as implements OnClickListener. The layout of this Activity includes two different Buttons, so we should check which one is pressed. After the declaration of the Buttons, setOnClickListener() method is called for each one. To handle the event, onClick() must be overridden. Notice that we need to make a check into the Handler Event callback, because multiple controls exist. So, when the Button with id nextBtn is pressed, a new Intent is initialized in order to lead the user to a new Activity.

4. Register an Event Listener to a custom Activity

We will create a custom Activity to show the other Event Listener approaches. We mention some characteristics for each approach:

4.1. Using an anonymous inner Event Listener class

The implementation of an anonymous inner Listener class is used for a single control into the Activity class. The advantage of this way is that the Event Handler can access the private data of the Activity as well as take more arguments at its callback. On the other hand, it works poorly for multiple controls with long code in the Event Handler callback , because it is difficult the maintenance of the code.

4.2. Using a separate Event Listener class

Another way is to use a class that implements an Event Listener and it is separated form the Activity. With this approach we can pass as many arguments as we want. In addition, it promotes the independence of the classes and the reusability of the code. In contrast, this approach requires a reference of the Activity to the separated class and the definition of public code in that Activity.

4.3. Using a layout XML file

The last approach we are going to show doesn’t require an implementation of Event Listener interface. We should define the Event Handler in the layout of the Activity and more specifically into the android:onClick attribute of the View component. After that, we should implement the respective function into the Activity. This way focuses on the “XML strategy” for a more consequent mode and provides different methods for different multiple controls. The main disadvantage of this approach is that it isn’t clear for the developers which handler corresponds to which control. Also, the handler method takes only the View argument while it returns void and that can’t be changed.

Now lets create the Activity that will includes the above approaches. Right click on src/com.javacodegeeks.android.eventhandletest → New → Class. Specify the name of the class and press Finish button.

EventHandleTest_ListenerActivity

Open src/com.javacodegeeks.android.eventhandletest/ListenerActivity.java and paste the code below.

ListenerActivity.java:

package com.javacodegeeks.android.eventhandletest;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class ListenerActivity extends Activity {
	private TextView text;
	private Button button1, button3;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.listener_view);
		
		text = (TextView) findViewById(R.id.text2);
		
		// anonymous inner Listener Class
		button1 = (Button) findViewById(R.id.button1);
		button1.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				text.setText("Inner Listener Class Way!");
				Toast.makeText(getApplicationContext(), "Into the ListenerActivity Class", 
						Toast.LENGTH_SHORT).show();
			}
		});
		button3 = (Button) findViewById(R.id.button3);
		button3.setOnClickListener(new ListenerImplement(this));
		
	}
	
	public void clickButton2(View view) {
		text.setText("onClick - XML Way!");
		Toast.makeText(getApplicationContext(), "Function that was declared in XML", 
				Toast.LENGTH_SHORT).show();
	}
	
	public void setTheText(String myText) {
		text.setText(myText);
		Toast.makeText(getApplicationContext(), "Calls ListenerImplement Class", 
				Toast.LENGTH_SHORT).show();
	}

}

The button1 uses the anonymous inner onClickListener, because the Event Listener is initialized into the setOnClickListener() method, as shown above. Also notice that the clickButton2() handler method was defined in the listener_view.xml layout, as you can see in Section 2. For the separate Listener class, have a look to the highlighted line in order to see how it is declared. Notice that ListenerImplement class can take as many arguments as we want.

To create this class right click on src/com.javacodegeeks.android.eventhandletest → New → Class. Name the class ListenerImplement as and press Finish button.

Now open src/com.javacodegeeks.android.eventhandletest/ListenerImplement.java and paste the following.

ListenerImplement.java:

package com.javacodegeeks.android.eventhandletest;

import android.view.View;
import android.view.View.OnClickListener;

public class ListenerImplement implements OnClickListener {

	private ListenerActivity calledActivity;
	
	public ListenerImplement(ListenerActivity previousActivity) {
		this.calledActivity = previousActivity;
	}
	@Override
	public void onClick(View arg0) {
		// TODO Auto-generated method stub
		this.calledActivity.setTheText("Into the ListenerImpementation Class!");
	}

}

As ListenerImplement class implements an Event Listener, the handler callback should be overridden. Pay attention that we call setTheText() method of the reference of ListenerActivity. That method should be public as you can ascertain in the previous code.

5. Define the custom Activity

We should define the ListenerActivity in the AndroidManifest.xml file of our project. So open AndroidManifest.xml file, go to the respective xml tab and paste the following.

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javacodegeeks.android.eventhandletest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.javacodegeeks.android.eventhandletest.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>
        
        <activity
            android:name="com.javacodegeeks.android.eventhandletest.ListenerActivity"
            android:label="@string/app_name" >
        </activity>
    </application>

</manifest>

6. Run the application

Now we are ready to run our application, so right click on our project → Run as → Android Application. The AVD will appear with the app loaded, as you can see in the picture below.

AVDEventHandleTest1

If we click “Listener Interface button”, callback method is enabled and the case with id buttonMain will be chosen. So, the TextView will change and a Toast will be appeared, as you can see below.

AVDEventHandleTest2

Now lets press the “Go to the next Activity” button. As MainActivity implements onClickListener, nextBtn will be chosen in the handler method, so the ListenerActivity will launch.

AVDEventHandleTest4

If we press “Inner Listener Class Button”, the Listener of the button1 will be set as an anonymous inner class. As you can see in the next picture, the appropriate messages will be derived.

AVDEventHandleTest3

Now we click “onClick Button”. That’s the approach of using a layout XML file, so clickButton2() handler method will be called and the TextView will change.

AVDEventHandleTest5

Finally lets press “Listener in Separate Class Button”. The ListenerImplement class will be initialized and it will call the public setTheText() method of ListenerActivity. A TextView will change and a Toast will launch, as you can notice in the picture below.

AVDEventHandleTest6

Download Eclipse Project

This was an example of Event Handling Controls in Android. Download the Eclipse Project of this example: EventHandleTest.zip

Katerina Zamani

Katerina has graduated from the Department of Informatics and Telecommunications in National and Kapodistrian University of Athens (NKUA) and she attends MSc courses in Advanced Information Systems at the same department. Currently, her main academic interests focus on web applications, mobile development, software engineering, databases and telecommunications.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button