Module 0257: Setting a event listener in general

Tak Auyeung, Ph.D.

January 29, 2017

1 About this module

2 Static versus dynamic event handler

In module 0254, we explored how to associate an event handler (in the form of a method of an Activity class) with a button. While the method works, it is also not very flexible because the association is done before compile time using the layout editor.

Android allows the dynamic creation of more user interface elements. While this makes little sense for static elements in an actiity, it makes sense in the case of items inside a list. As such, it is important to understand how to associate an event handler in Java code.

3 The humble View class

Most components that interfacs with an end user on the screen belong to a subclass of View. As a result, it makes sense to take a look at this seemingly simple class.

The full description of the View class is located at Android View. It is a rather long page! You can see that the list of public methods (methods that are can be used in classes that are not derived from View) is also long.

Using a browser search, locate the word “setOnClickListener” or just click here. Now click on the type of the argument to setOnClickListener.

It shows you the following:

public static interface View.OnClickListener

First of all, it is public, meaning that any code can use this definition as long as the View class is defined (as this is a nested definition in View).

Next, it is static. This means this interface cannot be used to instantiate new objects.

Last, it is an interface!

This is a concept that conceptually sets Java apart from C++. An interface is not a class, nor is it the replacement of a pure abstract class in C++.

An interface is, essentially, a filter. yes, a filter! An interface sets up constraints in terms of what methods must be defined in the argument that is being passed.

Let us take a look at the only requirement:

public static interface View.OnClickListener { 
  abstract void onClick(View v); 
}

First of all, abstract is redundant as it is impossible to define a method in an interface. Given that, the definition of OnClickListener is essentially saying the following:

“whatever the argument is being passed must have a method called onClick that takes on a View parameter and returns void.”

It does not restrict what else can be defined in the argument that is being passed!

This means the following class meets this requirement:

public class LetMeHandleClick implements View.OnClickListener { 
  void onClick(View v) { 
  } 
}

Given this definition, assuming v is a reference to a View, we can the use the following code to specify a click handler:

v.setOnClickListener(new LetMeHandleClick);

4 Anonymous class

Because there are times where a class is only used once to pass the filtering of an interface to instantiate one object, Java allows the definition of anonymous classes based on interfaces. For example, using our example earlier, it can be “simplified” as follows:

v.setOnClickListener(new OnClickListener() { public void onClick(View v) { }});

Of course, you may want to put some actual code in the method onClick!

This can be done any time you need to specify how an interactive element should respond to an event. Some of this will be specified in the onCreate method of an Activity class, but we are no longer limited.

5 The philosophical discussion

“Abstract super class plus multiple inheritance” versus “interface”. That is the main point of discussion among Java and C++ programmers.

First, the two approaches are philosophically different. One relies on the concept of inheritance, while the other relies on the concept of filtering. In C++, the use of an abstract class as the type of a parameter is essentially saying that “all arguments must be of a subclass of this.”

In Java, an interface is a filter. When an interface is the type of a parameter, it is saying “all arguments must supply these services.

The interface approach is a cleaner approach as interfaces are independent to the inheritence hierarchy. The addition of interfaces cannot adversely affect the inheritence hierarchy. It is always possible to derive a subclass of an existing one and use that to implement an interface.

The multiple inheritence approach, on the other hand, can run into issues when multiple super classes have the same abstract methods.