Listener objects
Anonymous inner classes
In the previous chapter, we already did some event handling. The part of the exercise where we incremented the TextView’s value for each button click was an exercise on declarative event handling . To bind a method name to a click event, we simply set a View’s android:onClick attribute to the name of a method in the associated Activity class. This is a low-ceremony and straightforward way to handle events but is limited to the “click” event. When you need to handle events like long clicks or gestures, you need to use event listeners—this is the topic of this chapter.
Intro to Event Handling
Common listener objects
Interface | Method | Description |
---|---|---|
View.OnClickListener | onClick() | This gets called when the user either touches and holds the control (when in touch mode) or focuses upon the item with the navigation keys and then presses the ENTER key |
View.OnLongClickListener | onLongClick() | Almost the same as a click, but only longer |
View.OnFocusChangeListener | onFocusChange() | When the user navigates onto or away from the control |
View.OnTouchListener | onTouch() | Almost the same as the click action, but this handler lets you find out if the user swiped up or down. You can use this to respond to gestures |
View.OnCreateContextMenuListener | onCreateContextMenu() | Android calls this when a ContextMenu is being built, as a result of a long sustained click |
The setOnClickListener is a member method of the android.view.View class, which means every child class of View has it. The method expects an OnClickListener object as an argument—this becomes the listener for the button control. When the button is clicked, the codes inside the onClick method will run.
We created the listener object by creating an instance of an anonymous class that inherits from View.OnClickListener; this type is declared as a nested interface in the View class.
Project details
Project detail | Value |
---|---|
Application name | EventHandling |
Company domain | Use your website name |
Language | Java |
Form factor | Phone and tablet only |
Minimum SDK | API 29 (Q) Android 10 |
Type of activity | Empty |
Activity name | MainActivity |
Layout name | activity_main |
The project will contain only two controls, the TextView, which came with the project when we used the wizard, and a Button view, which we are yet to add. The Button will intercept the events click and long click using an anonymous inner object.
Open the activity_main.xml file in the main editor if it’s not opened yet. You can find it in the Project Explorer window under the app ➤ res ➤ layout folder.
MainActivity.java
❶ We get a reference to the Button View; findViewById() should do that job just fine.
❷ In this case, we set up a listener object, an OnClickListener object, because we want to listen to click events.
❸ We override the onClick() method of the OnClickListener; this is where we put the codes we want to run when the Button is clicked.
❹ We display a Toast message. A Toast is a small pop-up message that disappears after a couple of seconds. You can use it to send small feedback to the user. Showing a Toast message is a two-step process. The first step is to create a Toast message using the makeText() function. It takes three parameters: (1) the context of the application, which in our case is the instance of MainActivity, (2) the message to show, and (3) how long to display it. The second step is to make it visible by calling the .show() method.
Handling Long Clicks
View objects can handle more than one kind of event. We can make our Button respond to both clicks (which we just did) and long clicks (which we’re about to do).
Long-click listener
It is very similar to the click handler in construction; we call the setXXXListener method and pass an instance of an anonymous listener class to it as an argument. We override the method (onLongClick, in this case) of the same listener object and put our codes in it—and that’s about it.
We could do another Toast message here, but I thought it might be instructive to use a different feedback mechanism, like Snackbar. Snackbar is like Toast, but instead of floating the text message, Snackbar’s message is anchored at the bottom of the screen. You can make it disappear after some timeout (just like Toast) or make the user swipe it away. Snackbar is more capable than Toast because you can include some actions in the message, like a small dialog box.
- 1.
Change the value of the layout container’s id property. By default, the layout container doesn’t have an id, and it’s usually okay because we didn’t have to refer to it from our Java code. Now, we will have to. The Snackbar’s construction requires that we refer to the layout container.
- 2.
Add a dependency in our Gradle file. The Snackbar isn’t readily available for use; you will have to include it in the project’s dependency file.
Let’s deal with the layout file first. Open the activity_main layout file, then change the value of the main layout file’s id property. By default, the layout container doesn’t have a value on its id property; we need to give it one right now because we need to reference it in code later.
The dependencies section of build.gradle
Codes for displaying Snackbar
The onLongClick method returns a boolean value. We returned true from the method to tell the Android Runtime that we have already consumed it; there’s no need for other handlers (like onClick) to consume it again. Had we returned false, the onClick handler would have kicked right in after the onLongClick method returns.
Complete code for MainActivity.java
Summary
You can set the android:onClick attribute to a name of a function if you want to handle simple click events.
Listener objects must be registered to the Android Runtime if you’re going to intercept certain events.
There are many kinds of listener objects, and they are listed as nested interfaces in the View class.
You can associate multiple listeners to the same View object.
Make sure to return false on an onLongClick method, if you don’t want other event handlers to handle it.