«

»

Feb 17

Print this Post

How to implement your own Listener in Android/Java

When you’re developing application, there is often a need to create your own controls/widgets/classes or to extend already available ones. And in most cases, you want this control/widget to be as flexible as possible. In order to achieve this, you have to create special events, which can be handled outside of your widget. Some of the popular examples are OnClickListener and OnKeyListener. But sometimes you need Events/Listener which aren’t predefined by the Java or Android SDK. In this case, you have to create your own Listener interface. In the last post, I’ve shown three different way on how to implement Listeners in your application. Now I’ll show you how to implement your own Listeners.
To demonstrate this, we’ll use our LoginExample activity and modify it slightly to act as a RegisterExample, where you can enter a username + password to create an account. Our goal is to create an application which will allow user to register/create a new account and while the user type his name in the user field, to check “live” if the username is already in use or not. After creating a new project, we’ll copy the main.xml and LoginExample.java file into their respective directories. The LoginExample.java will be renamed RegisterExample.java. First, we do some changes to the main.xml, in order to add a second password field and an TextView, which show us if the username is available or not, as well as changing some labels/texts. The final XML can be seen below
<?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"
    >
	<TextView
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:text="Please enter your desired username"
	    />
	<TextView
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:text="Login:"
	    />
	<EditText
		android:id="@+id/username"
		android:singleLine="true"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	/>
	<TextView
		android:id="@+id/userstatus"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    />
	<TextView
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:text="Password:"
	    />
	<EditText
		android:id="@+id/password"
		android:password="true"
		android:singleLine="true"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	/>
	<TextView
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:text="Repeat your password:"
	    />
	<EditText
		android:id="@+id/password2"
		android:password="true"
		android:singleLine="true"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	/>
	<Button
		android:id="@+id/register_button"
		android:text="Register"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	/>
	<Button
		android:id="@+id/cancel_button"
		android:text="Cancel"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	/>
	<TextView
		android:id="@+id/result"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    />
</LinearLayout>
If you now start the application, it should look like on the picture below. Screen1 Next, we clean up some of the code from LoginExample and remove unnecessary code as well as refactoring some variable names. The final code should look something like
package com.tseng.examples;

import com.tseng.examples.CheckUsernameEditText.OnUsernameAvailableListener;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class RegisterExample extends Activity {
	// Declare our Views, so we can access them later
	private EditText etUsername;
	private EditText etPassword;
	private EditText etPassword2;
	private Button btnRegister;
	private Button btnCancel;
	private TextView lblUserStatus;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Set Activity Layout
        setContentView(R.layout.main);

        // Get the EditText and Button References
        etUsername = (EditText)findViewById(R.id.username);
        etPassword = (EditText)findViewById(R.id.password);
        etPassword2 = (EditText)findViewById(R.id.password2);
        btnRegister = (Button)findViewById(R.id.register_button);
        btnCancel = (Button)findViewById(R.id.cancel_button);
        lblUserStatus = (TextView)findViewById(R.id.userstatus);

        // Set Click Listener
        btnRegister.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// create Account
			}
		});
        btnCancel.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// Close the application
				finish();
			}
		});
    }
}
So far, it looks like our LoginExample. Now the real work can begin. Our goal is to extend the EditText widget for user field and our own code to it, which will check if the username is already in use or not. First, we have to create a new class. We’ll call it CheckUsernameEditText. Once you create the application and it’s default supper class constructors, our first step is to create our own interface.
	// Define our custom Listener interface
	public interface OnUsernameAvailableListener {
		public abstract void onAvailableChecked(String username, boolean available);
	}
Our OnUsernameAvailableListener interface is quite simple and only has defined one abstract method. This method will be called, every time the username was checked and notify the user of the widget if the name was available or not. Now that we have defined the interface, we have to create a variable which will hold the listener by adding this line to top of our CheckUsernameEditText class.
	OnUsernameAvailableListener onUsernameAvailableListener = null;
Next one, we a setter to allow others to listen to this event.
	// Allows the user to set an Listener and react to the event
	public void setOnUsernameAvailableListener(OnUsernameAvailableListener listener) {
		onUsernameAvailableListener = listener;
	}
And last step is to add a small function which we will call every time to trigger the event (and we don’t have to repeat the checking code inside it every time)
	// This function is called after the check was complete
	private void OnUserChecked(String username, boolean available){
		// Check if the Listener was set, otherwise we'll get an Exception when we try to call it
		if(onUsernameAvailableListener!=null) {
			// Only trigger the event, when we have a username
			if(!TextUtils.isEmpty(username)){
				onUsernameAvailableListener.onAvailableChecked(username, available);
			}
		}
	}
So, that was the most important code in creating your own listeners. When ever you want to trigger this event, simply call OnUserChecked(username, available); Currently however, it’s never called. So we need to listen to user input and check the file. We’ll do this, by implementing the OnKeyListener interface to our CheckUserEditText class by changing the class definition to
public class CheckUsernameEditText extends EditText implements OnKeyListener {
Next we have to implement the onKey method, which will be called every time the user presses a key.
	@Override
	public boolean onKey(View v, int keycode, KeyEvent keyevent) {
		// We only want to handle ACTION_UP events, when user releases a key
		if(keyevent.getAction()==KeyEvent.ACTION_DOWN)
			return false;

		boolean available = true;

		// Whenever a user press a key, check if the username is available
		String username = getText().toString().toLowerCase();
		if(!TextUtils.isEmpty(username)){
			// Only perform check, if we have anything inside the EditText box
			for(int i=0; i<registeredUsers.length; i++) {
				if(registeredUsers[i].equals(username)){
					available = false;
					// Finish the loop, as the name is already taken
					break;
				}
			}
			// Trigger the Event and notify the user of our widget
			OnUserChecked(username, available);
			return false;
		}
		return false;
	}
This will check the entered text if the entered username is already available inside our registeredUsers array and set the available variables value to false if the name is already registered, otherwise leave it at it’s standard value of true. Lastly it will call OnUserChecked method, passing by username and it’s status to the listening function.
This will cause an error, because we haven’t defined registeredUsers yet. registeredUsers in our example is a simple String[] array, which will contain a few already registered names.
	final private static String[] registeredUsers = new String[] {
		// This is just a fixed List for tutorial purposes
		// in a real application you'd check this server sided or inside the database
		"tseng",
		"admin",
		"root",
		"joedoe",
		"john"
	};
In your real application you want to get this data from a remote server, an preferences file or from an sqlite database
Our application doesn’t receive any onKey events yet, because we haven’t registered the listener with the TextView’s onKeyListener. So we have to add this line in every of the 3 super class constructors
 //Set KeyListener to ourself
this.setOnKeyListener(this);
Now our CheckUsernameEditText widget is done. How ever, if we start the application we won’t notice a difference, because we haven’t replaced the username’s EditText widget with our own one. We need to change line 17 of our main.xml into
	<com.tseng.examples.CheckUsernameEditText
as well as change RegisterExample.java
	private EditText etUsername;
	// change into
	private CheckUsernameEditText etUsername;
and
        etUsername = (EditText)findViewById(R.id.username);
	// change into
        etUsername = (CheckUsernameEditText)findViewById(R.id.username);
last but not least, we have to set and define the listener to our new CheckUsernameEditText widget.
        // Set our new Listener to the Username EditText view
        etUsername.setOnUsernameAvailableListener(new OnUsernameAvailableListener(){
			@Override
			public void onAvailableChecked(String username, boolean available) {
				// Handle the event here
				if(!available){
					etUsername.setTextColor(Color.RED);
					lblUserStatus.setText(username + " is already taken. Please choose another login name.");
				} else {
					etUsername.setTextColor(Color.GREEN);
					lblUserStatus.setText(username + " is available.");
				}
			}
        });
The onAvailableChecked will be called every time after the check was done. We can put our code here to handle the outcome. The above’s example is pretty easy and will just change the text color of the CheckUsernameTextEdit field and update the lblUserStatus label wo notify the user his desired name is available or not. That’s all. Congratulation to your first own listener implementation. Now we can run our application. If everything worked well, it should look like the screen shots below. Screen2 Screen5 Screen3 Screen4 As always, there is the full source of the files (click on expand to make it visible)

Main.xml

<?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"
    >
	<TextView
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:text="Please enter your desired username"
	    />
	<TextView
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:text="Login:"
	    />
	<com.tseng.examples.CheckUsernameEditText
		android:id="@+id/username"
		android:singleLine="true"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	/>
	<TextView
		android:id="@+id/userstatus"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    />
	<TextView
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:text="Password:"
	    />
	<EditText
		android:id="@+id/password"
		android:password="true"
		android:singleLine="true"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	/>
	<TextView
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:text="Repeat your password:"
	    />
	<EditText
		android:id="@+id/password2"
		android:password="true"
		android:singleLine="true"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	/>
	<Button
		android:id="@+id/register_button"
		android:text="Register"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	/>
	<Button
		android:id="@+id/cancel_button"
		android:text="Cancel"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	/>
	<TextView
		android:id="@+id/result"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    />
</LinearLayout>

CheckUsernameEditText.java

package com.tseng.examples;

import com.tseng.examples.CheckUsernameEditText.OnUsernameAvailableListener;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class RegisterExample extends Activity {
	// Declare our Views, so we can access them later
	private CheckUsernameEditText etUsername;
	private EditText etPassword;
	private EditText etPassword2;
	private Button btnRegister;
	private Button btnCancel;
	private TextView lblUserStatus;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Set Activity Layout
        setContentView(R.layout.main);

        // Get the EditText and Button References
        etUsername = (CheckUsernameEditText)findViewById(R.id.username);
        etPassword = (EditText)findViewById(R.id.password);
        etPassword2 = (EditText)findViewById(R.id.password2);
        btnRegister = (Button)findViewById(R.id.register_button);
        btnCancel = (Button)findViewById(R.id.cancel_button);
        lblUserStatus = (TextView)findViewById(R.id.userstatus);

        // Set our new Listener to the Username EditText view
        etUsername.setOnUsernameAvailableListener(new OnUsernameAvailableListener(){
			@Override
			public void onAvailableChecked(String username, boolean available) {
				// Handle the event here
				if(!available){
					etUsername.setTextColor(Color.RED);
					lblUserStatus.setText(username + " is already taken. Please choose another login name.");
				} else {
					etUsername.setTextColor(Color.GREEN);
					lblUserStatus.setText(username + " is available.");
				}
			}
        });

        // Set Click Listener
        btnRegister.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// create Account
			}
		});
        btnCancel.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// Close the application
				finish();
			}
		});
    }
}

RegisterExample.java

package com.tseng.examples;

import java.lang.reflect.Array;

import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.EditText;
import android.widget.TextView;

public class CheckUsernameEditText extends EditText implements OnKeyListener {
	OnUsernameAvailableListener onUsernameAvailableListener = null;
	final private static String[] registeredUsers = new String[] {
		// This is just a fixed List for tutorial purposes
		// in a real application you'd check this server sided or inside the database
		"tseng",
		"admin",
		"root",
		"joedoe",
		"john"
	};

	public CheckUsernameEditText(Context context) {
		super(context);
		// Set KeyListener to ourself
		this.setOnKeyListener(this);
	}
	public CheckUsernameEditText(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// Set KeyListener to ourself
		this.setOnKeyListener(this);
	}
	public CheckUsernameEditText(Context context, AttributeSet attrs) {
		super(context, attrs);
		// Set KeyListener to ourself
		this.setOnKeyListener(this);
	}

	// Allows the user to set an Listener and react to the event
	public void setOnUsernameAvailableListener(OnUsernameAvailableListener listener) {
		onUsernameAvailableListener = listener;
	}
	// This function is called after the check was complete
	private void OnUserChecked(String username, boolean available){
		// Check if the Listener was set, otherwise we'll get an Exception when we try to call it
		if(onUsernameAvailableListener!=null) {
			// Only trigger the event, when we have a username
			if(!TextUtils.isEmpty(username)){
				onUsernameAvailableListener.onAvailableChecked(username, available);
			}
		}
	}
	@Override
	public boolean onKey(View v, int keycode, KeyEvent keyevent) {
		// We only want to handle ACTION_UP events, when user releases a key
		if(keyevent.getAction()==KeyEvent.ACTION_DOWN)
			return false;

		boolean available = true;

		// Whenever a user press a key, check if the username is available
		String username = getText().toString().toLowerCase();
		if(!TextUtils.isEmpty(username)){
			// Only perform check, if we have anything inside the EditText box
			for(int i=0; i<registeredUsers.length; i++) {
				if(registeredUsers[i].equals(username)){
					available = false;
					// Finish the loop, as the name is already taken
					break;
				}
			}
			// Trigger the Event and notify the user of our widget
			OnUserChecked(username, available);
			return false;
		}
		return false;
	}
	// Define our custom Listener interface
	public interface OnUsernameAvailableListener {
		public abstract void onAvailableChecked(String username, boolean available);
	}
}
That’s all. I hope you enjoyed it. If you have any questions, post it in the comments.

Permanent link to this article: http://tseng-blog.nge-web.net/blog/2009/02/17/how-implement-your-own-listener-android-java/

71 comments

4 pings

Skip to comment form

  1. pas cher nike free run womens

    Great website. A lot of useful info here.
    I am sending it to several friends ans additionally sharing
    in delicious. And obviously, thank you on your sweat!

  2. Indiana

    continuously i used to read smaller content which as well clear their motive, and
    that is also happening with this paragraph which I am reading now.

    Feel free to surf to my web site – Scaricare Fifa
    15 – Indiana -

  3. truck Driving Games

    Hi there, after reading this awesome paragraph i am as well
    cheerful to share my experience here with colleagues.

  4. serviced apartments hong kong tsim sha tsui

    When you rent a corporate apartment in Melbourne, you are assured of the
    best service. Spend your hard earned money on indulging in yourself rather
    than tipping hotel staff from the time to check in to the time you check-out.
    With so many more attractions to be explored, Edinburgh has the magic of making your holiday or
    business trip very interesting and exciting. If you have children, you can never
    go wrong with this place.

  5. moved here

    I’m not sure exactly why but this website is loading incredibly slow for me.
    Is anyone else having this issue or is it a problem on my end?

    I’ll check back later and see if the problem still exists.

  6. pygmy hippo south africa

    If you are going for finest contents like I do, just ppay a quick visit this web site everysay for the reason that it presents feature contents,
    thanks

    Visit my website; pygmy hippo south africa

  7. エムシーエム 時計

    I was curious if you ever thought of changing the layout of your website?
    Its very well written; I love what youve got to say. But maybe you could
    a little more in the way of content so people could connect with
    it better. Youve got an awful lot of text for only having 1 or 2 images.
    Maybe you could space it out better?

  8. aneka kreasi resep masakan

    I’m extremely pleased to discover this site. I wanted to thank you for ones time due to this wonderful read!!
    I definitely savored every part of it and i also have you saved
    to fav to look at new stuff on your web site.

  9. books and info

    Quality articles or reviews is the secret to interest the users to pay a quick visit the site, that’s
    what this web site is providing.

  10. attrition

    I’ll immediately clutch your rss as I can’t to find your e-mail subscription hyperlink or e-newsletter service.
    Do you have any? Please permit me realize in order that I may just subscribe.
    Thanks.

  11. invest in gold ira

    Though they may allow we to buy ETF’s or mutual funds which trade in line with all the price of silver, gold, and other precious metals, this might be not the same because owning bodily gold.

  12. Harga samsung Galaxy V

    Moving further, lets talk about the memory storage capacity of Samsung Galaxy S2.
    Step 6 – Limit the Vibrate Function – Use the menu
    item “Turn off haptic feedback” which will mean
    that you can turn off the vibration of the
    device by pressing any keys on screen. Now, if you buy a new Samsung Galaxy S2, then you’ll also need Samsung Galaxy S2 accessories to protect your
    cell phone.

  13. uniquegiftsforparents.webstarts.com

    Good post but I was wondering if you could write a litte more
    on this subject? I’d be very thankful if you could elaborate a little bit
    more. Thank you!

    Look into my pae :: tea roses (uniquegiftsforparents.webstarts.com)

  14. boobs

    I’m not certain where you’re getting your info, however
    good topic. I must spend a while studying more
    or working out more. Thanks for fantastic info I
    used to be searching for this info for my mission.

  15. ดูดไขมัน

    Hey there, You have done a fantastic job. I will definitely digg it and personally recommend to my
    friends. I’m confident they will be benefited from this website.

  16. recineli kablo

    I just like the valuable info you provide to your articles.
    I will bookmark your weblog and test once more here regularly.
    I’m fairly certain I’ll be told a lot of new stuff right here!

    Best of luck for the next!

  17. Ashly

    This website was… how do I say it? Relevant!! Finally I’ve found something which helped me.
    Kudos!

    My blog world wide web; Ashly,

  18. c++ 2010 redistributable package

    Hello to every body, it’s my first pay a visit of this website;
    this webpage includes amazing and really good
    data designed for visitors.

  19. jesus christ

    Fastidious respond in return of this issue with genuine arguments and describing the whole thing on the
    topic of that.

  20. reklama

    Everything is very open with a really clear explanation of the issues.
    It was definitely informative. Your site is very helpful.
    Thanks for sharing!

  21. acne drugs

    You can definitely see your expertise in the work you write.
    The sector hopes for more passionate writers such as you
    who aren’t afraid to mention how they believe.
    At all times follow your heart.

  1. Tweets that mention How to implement your own Listener in Android/Java | Tseng's dev blog -- Topsy.com

    […] This post was mentioned on Twitter by Shoaib Shaikh. Shoaib Shaikh said: your very own listeners [Droid] http://tseng-blog.nge-web.net/blog/2009/02/17/how-implement-your-own-listener-android-java/ […]

  2. Cómo implementar nuestros Listener en Android | Sentido Droid

    […] How to implement your own Listener in Android/Java […]

  3. The Welgevonden Private Game Reserve | kristaguido

    […] many wildlife parks and reserves for visitors and residents to enjoy to be found within the Western groote schuur zoo cape town of South […]

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>