Sunday, December 9, 2012

Android beginner tutorial: Part 15 - Adding click listeners

Today we'll begin learning about event listeners in Android and create a simple click listener.

The whole event listening process is a little different from the one in AS3. The View class includes 6 interfaces: OnClickListener, OnLongClickListener, OnFocusChangeListener, OnKeyListener, OnTouchListener and OnCreateContextMenuListener.

To add a listener of a specific type to an object that extends a View, use one of the object's methods that listens to one of those 6 event types (for example, if you want to listen to a click event, use setOnClickListener() method).

Each handler is also a function created using one of the View's interfaces (for example View.OnClickListener()).

If you're new to Java, you'll find some syntax differencies from AS3 as well. For example, the type of the returned value is specified before the name of the function. The way parameters are written is also different.

Let's compare how functions are declared in AS3 and in Java.

First, in AS3:

public function test(str:String):void{
// ...
}

Now in Java:

public void function test(String str){
// ...
}

Keeping all of that in mind, let's try creating a simple application that has 2 buttons that listen to click events and change text based on which button the user clicked.

Firstly, go to activity_main.xml file and use this code to create 2 buttons and a text field:

<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity" >
        
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_1"
        android:id="@+id/button1"/>
    
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_2"
        android:id="@+id/button2"/>
    
    <TextView 
        android:id="@+id/myText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

</LinearLayout>

The button labels are taken from strings.xml. Here are the contents of that xml file:

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

    <string name="app_name">Code For Food Test</string>
    <string name="btn_1">Button 1</string>
    <string name="btn_2">Button 2</string>
    <string name="menu_settings">Settings</string>

</resources>

Now go to src directory, open the package inside of it and then MainActivity.java file.

Here's the code that's automatically generated:

package com.kircode.codeforfood_test;

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

public class MainActivity extends Activity {

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

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}

}

You can see that java classes are very similar to AS3, even though in some parts the syntax differs.

Let's declare a variable of type TextView, which will reference our existing text field.

Declare the variable like this:

private TextView myField;

In AS3, it would look like this:

private var myField:TextView;

In Eclipse IDE, you can press Ctrl+Shift+O to import all the needed classes to your current class instantly. Very useful! You should do that now.

After the variable is declared, let's set it to our existing text field. Do this in the onCreate() function after the code that is already in it:

myField = (TextView)findViewById(R.id.myText);

In AS3 the same would read as:

myField = myText as TextView;

The reason the ID of the element has the R.id. prefix is because all the resource references are stored in R.java class, which is automatically generated from our xml layouts by Android SDK. Cool!

After that's done, let's add a click listener and make the handler change the text.

Declare a new variable with "final" variable type (which is a type like public or private, its purpose is to indicate that the variable will not be changed anymore) and set its value to the element with id button1:

final Button button1 = (Button)findViewById(R.id.button1);

Then call this object's setOnClickListener() function. As the parameter pass a new View.OnClickListener() function, inside of it add a new public function called onClick(), which will act as the event handler. Update the text in the onClick() function:

button1.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
myField.setText("The first button was clicked!");
}
});

Do the same with the second button:

final Button button2 = (Button)findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
myField.setText("The second button was clicked!");
}
});

Full java code:

package com.kircode.codeforfood_test;

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

public class MainActivity extends Activity {

private TextView myField;

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

myField = (TextView)findViewById(R.id.myText);

final Button button1 = (Button)findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
myField.setText("The first button was clicked!");
}
});

final Button button2 = (Button)findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
myField.setText("The second button was clicked!");
}
});

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}

}

Now you can run this on your device or an emulator and see that the text changes when you click on the buttons.

Pretty neat so far!

Thanks for reading!

No comments:

Post a Comment