I’ve seen many people asking how to implement Listeners in their applications. Implementing a Listener is quite easy. There are 3 ways to implement an Listener and the have their advantages and disadvantages.
The tree way to implement Listeners are
- Inline Implementation
- Using the
implementskeyword - By using variables
We’ll use our good old LoginExample application, created in previous tutorial which can be found at Android: Your first Android Application.
Inline Implementation
The first way, to implement an listener is by using Inline Implementation. In Inline Implementations we create an anonymous listener, define and pass it the the setLisener functions in the same step.
We did this already in our First Android Application Tutorial.
package com.tseng.examples;
...
public class LoginExample extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// Set Click Listener
btnLogin.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Check Login
String username = etUsername.getText().toString();
String password = etPassword.getText().toString();
if(username.equals("guest") && password.equals("guest")){
lblResult.setText("Login successful.");
} else {
lblResult.setText("Login failed. Username and/or password doesn't match.");
}
}
});
btnCancel.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Close the application
finish();
}
});
}
}
As we see, we create an anonymous class there by adding { … code … } behind the new OnClickListener interface and implementing the necessary onClick(View v) method.
Advantages
- Small and tidy
- Easy to implement
- Less overhead
Disadvantages
- Inflexible
- Can’t be reused
- Can be a bit harder to maintain
Usage
Inline implementations are usually used for short 1-time methods, for example if you have a button which closes the application or which displays, you don’t need to add an implementation to your class or create a variable, making your code less readable.
Using the “implements” keyword
The second method to implement an Listener is by adding an interface to your base class. In java you can do this by adding “implements Interfacename” to the class declaration.
package com.tseng.examples;
...
public class LoginExampleImplements extends Activity implements OnClickListener {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// Set Click Listener
btnLogin.setOnClickListener(this);
btnCancel.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v==btnLogin) {
// Check Login
String username = etUsername.getText().toString();
String password = etPassword.getText().toString();
if(username.equals("guest") && password.equals("guest")){
lblResult.setText("Login successful.");
} else {
lblResult.setText("Login failed. Username and/or password doesn't match.");
}
} else if(v==btnCancel) {
// Close the application
finish();
}
}
}
As we can see, the “onClick(View v)” is being declared inside our LoginExample class and additionally we set the listener by passing a reference to our class to by using btnLogin.setOnClickListener(this);. This works, because we implemented this interface within our class public class LoginExampleImplements extends Activity implements OnClickListener. You may also have noticed, that we add the same listener to both buttons. Because both of the buttons use the same listener, we need to differentiate which one was clicked. This can be done by comparing the View v reference with the Button btnLogin reference as seen below:
if(v==btnLogin) {
// Check Login
...
} else if(v==btnCancel) {
// Close the application
...
}
Advantages
- Methods/Listener can be reused in many different widgets
- Code of multiple Listeners is located in the same section of code
- Can be used to create one method for similar Listeners
Disadvantages
- Can contain much unnecessary and untidily code, if the actions executed are to different and you have to add an
if / elseif / elseblocks, making the code hard to read - You can only have one implementation of this Listener per class
Usage
This method is best used, when you have multiple widgets/elements using same or similar listeners (i.E. doing a calculation or check on a click or key press). The example above is not the best example on the usage of the implement method. Let’s imagine, you have a calculator and have 14 buttons and you want to update the formula you entered after every calculator button is pressed, you could implement it in the following way shown below.
package com.tseng.examples;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class CalculatorExample extends Activity implements OnClickListener {
...
@Override
public void onClick(View v) {
if(v==btnCalculate) {
// Parse and calculate formula
String formula = etFormula.getText().toString();
Double result = performCalculation(formula);
// Update the result TextView
tvResult.setText(Strint.valueOf(result));
// End it as we don't need or want to update the Formula field
return;
}
// Get the button
Button button = (Button)v;
// Get the String/Button descritpion
String strToAppend = button.getText().toString();
// Update Formula
etFormula.append(strToAppend);
}
}
You could add this Listener to every of the calculators button and only need to define one Listener. When the buttons are clicked, the button text (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +, –, /, * etc.) will be added to the TextView containing the formula. However, if you press the calculate button, it won’t add a = to the formula, but will instead perform the calculation.
This is best used when you’re creating your own widgets and want to to handle clicks (assuming there are only few clickable elements there)
By using Variables
This one is very similar to the previous one, with the difference that you don’t add the implementation to your class, but instead hold a reference to the Listener in a variable.
In our LoginExample it would look like this
package com.tseng.examples;
...
public class LoginExampleVariableImplementation extends Activity {
...
OnClickListener myClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
if(v==btnLogin) {
// Check Login
String username = etUsername.getText().toString();
String password = etPassword.getText().toString();
if(username.equals("guest") && password.equals("guest")){
lblResult.setText("Login successful.");
} else {
lblResult.setText("Login failed. Username and/or password doesn't match.");
}
} else if(v==btnCancel) {
// Close the application
finish();
}
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// Set Click Listener
btnLogin.setOnClickListener(myClickListener);
btnCancel.setOnClickListener(myClickListener);
}
}
Basically we create it anonymous Listener with the difference that we hold a reference to it. This allows us to add this Listener to more than only one widget. The main difference to the implements keyword method is, that we can have more than one Listener inside our class declared and use them more than once.
Advantages
- Can be reused
- You can have more than one Listener of the same kind in your class
- You can keep your listeners organized in one place, making your code easier to read
Disadvantages
- Too many listeners can make the code rather complicated to read
Usage
This is best to use if you have different Listeners for the same action i.e. 2 different OnClickListener which do a completely different task.
Another very important usage for this variant is if you’re implementing your own Listeners to your widgets, you could have a variable which can be assigned by the users of your widgets
package com.tseng.examples;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MyWidget extends View {
...
OnClickListener myClickListener = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
public void setOnClickListener(OnClickListener listener) {
myClickListener = listener;
}
private onClick(View v) {
// Check if Listener was set and call the onClick Method
if(myClickListener!=null)
myClickListener.onClick(v);
}
private void handleEventsMethod() {
...
// handle clicks
onClick(this);
}
}
This allows us to dynamically set the Listener to our widget without knowing what the listener will actually do with the click, as it can be implemented in any way the user or programmer wants it to be.
Summary
So there are no “right” ways to implement a Listener. It all depends on the situation and/or your personal preferences.
| Method | Recommended usage |
|---|---|
| Inline | Best to use for short and one time only listeners, like closing an application or displaying an message or call another Activity/Dialog |
implements-keyword |
If you have only one listener in your class (i.e. your own widget) or the listeners shares a fairly similar code/task, like the Calculator Example above |
| Variables | If you have many Listeners with very different codebases and tasks or creating your own widget and want to allow your users to handle the events (i.e. click or key press events). |
32 comments
11 pings
Skip to comment form ↓
toveantinee
March 9, 2009 at 13:53 (UTC 1) Link to this comment
Hello, I can’t understand how to add your blog in my rss reader
Tseng
March 9, 2009 at 14:31 (UTC 1) Link to this comment
Hi,
the links for the feeds are on the right side of the navigation under Resources -> Subscribe.
What RSS Reader are you using? Webbased or a real one?
The links for the feeds are
RSS 2.0: http://tseng-blog.nge-web.net/blog/feed/
RSS 2.0 (Comments): http://tseng-blog.nge-web.net/blog/comments/feed/
RSS 0.92: http://tseng-blog.nge-web.net/blog/feed/rss/
Atom 0.3: http://tseng-blog.nge-web.net/blog/feed/atom/
Depending on what format your feed reader requires, you have to choose the correct URL yourself. i.e. if your Reader is supporting RSS 2.0, then pick the first one, if not try atom or RSS 0.92 feed
Vince Delmonte
April 15, 2009 at 07:56 (UTC 1) Link to this comment
I can tell that this is not the first time at all that you mention this topic. Why have you decided to touch it again?
Miplobinobeby
April 15, 2009 at 10:52 (UTC 1) Link to this comment
Why don’t my username and password work?
Tseng
April 18, 2009 at 12:05 (UTC 1) Link to this comment
For the example the username and password is hardcoded to username guest and password guest.
You can see it in this line
f(username.equals(“guest”) && password.equals(“guest”)){
// …
}
In a real application you have to use a database or website to do the verification of the login data. Maybe post a piece of code, if you have altered it or built it in your application?
Arianabura
May 13, 2009 at 10:47 (UTC 1) Link to this comment
I really liked this post. Can I copy it to my site? Thank you in advance.
Tseng
May 13, 2009 at 22:17 (UTC 1) Link to this comment
Sure, if you post a backlink to the original post, it’s fine for me.
fxmen
May 22, 2009 at 14:58 (UTC 1) Link to this comment
I just want to let you know that I have benefited from the information here. Thanks a lot.
KeHoeff
May 28, 2009 at 21:12 (UTC 1) Link to this comment
hey this is a very interesting article!
PypePilky
June 5, 2009 at 22:16 (UTC 1) Link to this comment
Very nice collection of information on that question. Thanks to the author. I have been looking for such an article since January! Thank you again!
Felix-Tiez
August 29, 2009 at 14:39 (UTC 1) Link to this comment
I cannot believe this will work!
Bill Bartmann
September 2, 2009 at 14:05 (UTC 1) Link to this comment
Great site…keep up the good work.
Elcorin
September 5, 2009 at 20:50 (UTC 1) Link to this comment
Thank you! I would now go on this blog every day!
Zoran
September 10, 2009 at 07:23 (UTC 1) Link to this comment
Hi, Thank you! I would now go on this blog every day!
Thank you
Zoran
September 14, 2009 at 10:43 (UTC 1) Link to this comment
Hi,
Onload of page my antivirus put alert, check pls.
Tseng
September 14, 2009 at 16:25 (UTC 1) Link to this comment
It does? Where? You could try to post a picture, to see if it happend on one of the ads (on which I don’t really have influence which is displayed). But I doubt Google would allow malicious ads to be displayed
Robor
September 17, 2009 at 20:10 (UTC 1) Link to this comment
Hi,
Super post, Need to mark it on Digg
Have a nice day
Robor
Bodyc
September 20, 2009 at 07:39 (UTC 1) Link to this comment
Hi, Amazing! Not clear for me, how offen you updating your tseng-blog.nge-web.net.
Thank you
Bodyc
nintendost
November 18, 2009 at 05:54 (UTC 1) Link to this comment
Article very interesting, I will necessarily add it in the selected works and I will visit this site
Miato
November 18, 2009 at 08:39 (UTC 1) Link to this comment
Completely I share your opinion. I think, what is it good idea.
Have a nice day
Adam
April 8, 2010 at 09:24 (UTC 1) Link to this comment
A better alternative to using
if(v==buttonx) {}
else if(v==buttony) {}
would be to use a switch statement.
switch(v) {
case buttonx:
//events
break;
case buttony:
//events
break;
default:
//else
}
This approach is much easier on the eyes.
Adam
April 8, 2010 at 22:46 (UTC 1) Link to this comment
Disregard the above. The switch statement argument cannot be type view…
Doccie
June 23, 2010 at 09:22 (UTC 1) Link to this comment
Great post… Coming from an AS3 background, I had some trouble wrapping my head around this approach when reading the android docs, but your post was very clear and precise, thanks!
Sachin
November 19, 2010 at 07:35 (UTC 1) Link to this comment
Great post,thanks!
sony ericsson w580i
January 23, 2011 at 10:23 (UTC 1) Link to this comment
This is the best email in a browser that I’ve read in a while.
jamie
February 1, 2012 at 22:52 (UTC 1) Link to this comment
Does this mean someone can hack your phone and listen to your conversations?
khanh tran
June 24, 2012 at 16:28 (UTC 1) Link to this comment
hi Tseng
can u explain more about the last example (public class MyWidget extends View)
Thank u in advance
carpinteyronjg
August 28, 2012 at 18:59 (UTC 1) Link to this comment
Here let me learn more knowledge!
joyson
September 14, 2012 at 07:10 (UTC 1) Link to this comment
Very Helpful Tutorial…Looking forward you add some more tutorials to share your knowledge..
Joey
November 29, 2012 at 23:19 (UTC 1) Link to this comment
You forgot about the method of using “inner classes”. I’d like to see this added for thecomparison.
online hard drive backup
May 6, 2013 at 16:27 (UTC 1) Link to this comment
I’m really loving the theme/design of your weblog. Do you ever run into any browser compatibility problems? A number of my blog visitors have complained about my website not operating correctly in Explorer but looks great in Chrome. Do you have any suggestions to help fix this problem?
That This Broadoaks Country House In Windermere
May 12, 2013 at 20:54 (UTC 1) Link to this comment
What’s up to all, the contents existing at this site are really amazing for people experience, well, keep up the good work fellows.
RxRick’s Blog
December 8, 2009 at 16:43 (UTC 1) Link to this comment
[...] I finally stumbled upon a brilliant blog which explains all the different methods, and lists the pros and cons of each: Implementing listeners in your Android application [...]
How to implement your own Listener in Android/Java | Tseng's dev blog
April 29, 2010 at 16:51 (UTC 1) Link to this comment
[...] dev blog A developers blog « Implementing Listeners in your Android/Java application SavedState: Preserve data when your Activity is recreated – Part 1 [...]
Android: Your first Android Application | Tseng's dev blog
April 29, 2010 at 18:39 (UTC 1) Link to this comment
[...] listeners only gets used once and their code is pretty small. If you want to know more check out my Implementing Listeners in Android/Java [...]
SavedState: Preserve data when your Activity is recreated – Part 1 | Tseng's dev blog
April 29, 2010 at 19:38 (UTC 1) Link to this comment
[...] item from the auto-complete list. Implementing Listeners is already explain in my previous post “Implementing Listeners in Android/Java” and “How to implement your own Listeners in [...]
extends view + onDraw() + listener - Android-Hilfe.de
May 19, 2010 at 10:47 (UTC 1) Link to this comment
[...] [...]
Caught By .Net!
May 27, 2010 at 21:26 (UTC 1) Link to this comment
Implementing Listeners in your Android/Java application…
…
Verwendung von Listener - Android-Hilfe.de
June 2, 2010 at 12:47 (UTC 1) Link to this comment
[...] [...]
Ways to Implement an OnClick Listener in Android
October 7, 2010 at 05:29 (UTC 1) Link to this comment
[...] http://tseng-blog.nge-web.net/blog/2009/02/14/implementing-listeners-in-your-android-java-applicatio… [...]
смотрите новости mmorpg
January 11, 2012 at 03:18 (UTC 1) Link to this comment
смотрите новости mmorpg…
[...]Implementing Listeners in your Android/Java application | Tseng’s dev blog[...]…
Activity! Criando Interfaces Gráficas no Android! | Android On Board
August 24, 2012 at 03:15 (UTC 1) Link to this comment
[...] Link que demonstra outras formas de tratar eventos de componentes Button no Android: [...]
aListView – Displaying and using a ListView | Breinbaas Blog
October 15, 2012 at 18:47 (UTC 1) Link to this comment
[...] line 5: definition of the itemclicked listener, I like to put these functions in variables instead of implemting the directly, there is a great blog about the ways to implement listeners here. [...]