On Android, there are more than one way to listen for events that interact between users and applications. For events in the user interface, the listener method is to intercept these events from a particular view object that interacts with the user. The view class provides the appropriate means.
In the various view classes used to build layouts, you may notice that some common callback methods appear to be useful for user interface events. These methods are invoked by the Android framework when the associated action of the object occurs. For example, when a view (such as a button) is touched, the Ontouchevent () method on the object is invoked. However, to listen to this event, you must extend the class and override the method. Obviously, it's absurd to extend each view object that you want to use (just to handle an event). This is why the view class also contains a collection of nested interfaces that contain a much simpler callback function. These interfaces, called event listeners, are the "tickets" used to intercept the interaction between the user and your interface (listeners).
When you are more commonly using event listeners to listen for user actions, there is always a time when you might want to extend a view class to create a custom component. Maybe you want to extend the button class to make something more fancy. In this case, you will be able to make the event handler handlers class to define the default event behavior for your class.
Events Listener Event Listeners
An event listener is an interface to a view views class that contains a separate callback method. These methods are invoked by the Android framework when listeners registered in the view are triggered by user interface actions. The following callback methods are included in the event listener interface:
OnClick (): Included in View.onclicklistener. When the user touches the item (in touch mode), either by browsing the key or by tracking the ball to focus on the item, then pressing the "Confirm" button or pressing the tracking ball is invoked.
Onlongclick (): Included in View.onlongclicklistener. When the user touches and controls the item (in touch mode), or focuses on the item by browsing the key or tracking the ball, it is called when the "confirm" key is pressed or the tracking ball (a second) is pressed.
Onfocuschange (): Included in View.onfocuschangelistener. Called when the user uses the browse key or tracks the ball to browse into or out of the item.
OnKey (): Included in View.onkeylistener. Invoked when a user focuses on this item and presses or releases a key on the device.
Ontouch (): Included in View.ontouchlistener. When a user performs an action that is invoked as a touch event, including press, release, or any movement gesture on the screen (within the bounds of this item).
Oncreatecontextmenu (): Included in View.oncreatecontextmenulistener. Called when a context menu is being created (as a result of an ongoing "long Click" Action).
These methods are the only "tenants" of their corresponding interfaces. To define these methods and to handle your events, implement this nested interface in your activity or define it as an anonymous class. Then, pass one instance of your implementation to the respective View.set ... Listener () method. (for example, call Setonclicklistener () and pass it to your Onclicklistener implementation. )
The following example shows how to register a click Listener for a button:
Create an anonymous implementation of Onclicklistener
private Onclicklistener mcorkylistener = new Onclicklistener () {public
void OnClick (View v) {
//does something when the ' button is clicked
}
};
protected void OnCreate (Bundle savedvalues) {
...
Capture our button from layout
button button = (button) Findviewbyid (r.id.corky);
Register the OnClick listener with the implementation above
Button.setonclicklistener (Mcorkylistener);
...
}
You may find it more convenient to make Onclicklistener a part of the activity. This avoids additional class loading and object allocation. Like what:
public class Exampleactivity extends activity implements Onclicklistener {
protected void onCreate (Bundle savedvalues) {
...
Button button = (button) Findviewbyid (r.id.corky);
Button.setonclicklistener (this);
}
Implement the Onclicklistener callback public
void OnClick (View v) {
//does something when the ' button is clicked
}
...
}
Note that the onclick () callback in the above example does not return a value, but some other event listeners must return a Boolean value. Cause and event related. For some of these, the reasons are as follows:
Onlongclick () – Returns a Boolean value indicating whether you have consumed this event and should not handle it further. That is, returning true means that you have handled the event and so on, and returning false indicates that you have not handled it and/or that this event should continue to be given to other On-click listeners.
OnKey () – Returns a Boolean value indicating whether you have consumed this event and should not handle it further. That is, returning true means that you have handled the event and so on, and returning false indicates that you have not handled it and/or that this event should continue to be given to other on-key listeners.
Ontouch ()-Returns a Boolean value indicating whether your listener has consumed this event. The important thing is that this event can have multiple movements that follow each other. Therefore, if you return False when you receive a downward action event, it indicates that you have not consumed the event and are not interested in subsequent actions. Then you will not be called by other actions in the event, such as gestures or the last occurrence of an upward action event.
Remember that key events are always submitted to the view in which the current focus is located. They are distributed from the top level of the view hierarchy and then down until the appropriate target is reached. If your view (or a child view) currently has the focus, you can see that the event is distributed through the Dispatchkeyevent () method. In addition to intercepting key events from your view, there is an alternative scenario where you can use OnKeyDown () and OnKeyUp () to receive all events in your activity.
Note: Android will first invoke the event handler, followed by the appropriate default processor in the class definition. In this way, returning true from these things listeners stops the event from propagating to other event listeners and also blocks the callback function of the missing event handler in the view. So when you return true, confirm that you want to terminate the event.
Events Processor Event handlers
If you create a custom component from the view, you will be able to define some callback methods to be used as the default event handler. In the documentation for creating custom components building custom components, you will learn some common callback functions that are used as event handling, including:
- OnKeyDown (int, keyevent)-is invoked when a new keystroke event occurs.
- onKeyUp (int, keyevent)-is invoked when an up arrow event occurs.
- Ontrackballevent (motionevent)-is invoked when a tracking ball motion event occurs.
- Ontouchevent (motionevent)-called when a touch-screen move event occurs.
- Onfocuschanged (boolean, int, Rect)-Called when the view Gets or loses focus.
You should know that there are other methods that are not part of the view class, but can directly affect the way you handle events. So, when managing more complex events in a layout, consider these methods:
- Activity.dispatchtouchevent (motionevent)-This allows your activity to capture all touch events before distributing to the window.
- Viewgroup.onintercepttouchevent (motionevent)-This allows one view group ViewGroup to observe these events when distributing to a child view.
- Viewparent.requestdisallowintercepttouchevent (Boolean)-calls this method on top of a parent view to indicate that it should not pass through Onintercepttouchevent ( Motionevent) to capture touch events.
Touch mode
When users use the arrow keys or track the ball to navigate the user interface, it is necessary to set the focus on the item that the user can manipulate, such as a button, so that the user can know which item will accept the input. However, if the device has touch capabilities and the user interacts with the interface through touch, there is no need to highlight items or set the focus to a particular view. In this way, there is an interactive mode called "Touch mode."
For a touch-capable device, once the user touches the screen, the device will enter the touch mode. Since then, only Isfocusableintouchmode () is a true view that can be focused, such as a text editing part. Other touch views, such as buttons, will not receive the focus when touched, and they will simply trigger on-click listeners when they are pressed. Any time the user presses the arrow key or scrolls the tracking ball, the device exits the touch mode and then takes a view to receive the focus, and the user may not be able to touch the screen to recover the interface interaction.
Touch mode state is maintained throughout the system (all windows and activities). In order to query the current state, you can call Isintouchmode () to see if the device is currently in touch mode.
Handling Focus Handling
The framework will handle the regular focus movement based on user input. This includes changing the focus when the view is deleted or hidden, or when a new view appears. Views indicate their willingness to gain focus through the isfocusable () method.
To change whether the view can accept the focus, you can invoke Setfocusable (). In touch mode, you can query whether a view allows you to receive focus by Isfocusableintouchmode (). You can change it by Setfocusableintouchmode () method. Focus movement is based on an algorithm that finds the nearest neighbor in a given direction. In rare cases, the default algorithm may not match the developer's willingness behavior. In these cases, you can provide explicit overrides through the XML attributes in the following layout file: Nextfocusdown, Nextfocusleft, Nextfocusright, and Nextfocusup. Adds one of these properties to the view that has lost focus. Defines the ID of the view in which the property value has focus. Like what:
<linearlayout
android:orientation= "vertical" ...
>
<button android:id= "@+id/top"
android:nextfocusup= "@+id/bottom"
.../>
<button android:id= "@+id/bottom"
android: nextfocusdown= "@+id/top" ...
/>
</LinearLayout>
Typically, in this vertical layout, browsing from the first button or down from the second button will not move anywhere else. Now that the top button has defined the bottom button as Nextfocusup (and vice versa), the browsing focus moves from top to bottom and from bottom to top.
If you want to declare a focused view in the user interface (usually not), you can add android:focusable XML attributes to the view in your layout definition. Set its value to true. You can also use Android:focusableintouchmode to declare a view in touch mode to be focused.
To request a specific view that receives focus, call Requestfocus ().
To listen for the focus event (which is notified when a view gains or loses focus), use Onfocuschange (), as described in event listeners above.
The difference between touch events and click events
For a view control on the screen, how does Android differentiate between triggering ontouchevent, onclick, or Onlongclick events?
In Android, a user action can be handled separately by different views, and will fully respond to the user once UI action is called the consumption of the event (consume), so what is the order in which Android delivers events? And under what circumstances did you decide to consume the event?
Figuring out these issues is important for writing code that responds correctly to UI actions, especially when different view on the screen needs to respond differently to the UI, a typical example of a user placing a widget on the desktop, Then when the user is doing various operations for the widget, the desktop itself sometimes has to respond to the user's actions, and occasionally ignore. Only by understanding the mechanism of event triggering and delivery is it possible to ensure that the UI controls still respond correctly to user actions in situations where the interface layout is very complex.
1. Ontouchevent
The 3 most commonly used events in Ontouchevent are: Action_down, Action_move, action_up.
These three events identify the most basic user touch screen operation, and the meaning is clear. Although we use them every day, there is one point to note that the Action_down event, as the starting event, is more important than action_move and action_up, if Action_move or action_up occur, Then there must have been a action_down.
There are some interaction mechanisms that can be realized from the Android source code based on the understanding of this different importance, and there are also explicit references in the SDK, for example, in the ViewGroup onintercepttouchevent method, if the Action_ True is returned in the down event, then the subsequent events are sent directly to the ontouchevent instead of continuing to the onintercepttouchevent.
2. OnClick, Onlongclick and Ontouchevent
I've read a post that says that if you deal with ontouchevent in a view, you don't have to deal with the onclick anymore, because Android only triggers one of these methods. This understanding is not very correct, for a view, the user completes a touch operation, apparently the signal from the sensor is the finger press and lift up two operations, we can understand as a click, can also be understood to have occurred once Action_down and Action_up, So how does Android understand and deal with it?
In Android, the onclick, Onlongclick trigger is associated with Action_down and action_up, and in the timing, if we were to override the onclick in a view, Onlongclick and Ontouchevent, Ontouchevent is the first to capture Action_down and action_up events, followed by the possibility of triggering onclick or onlongclick. The main logic is implemented in the Ontouchevent method in View.java:
Case Motionevent.action_down:
mprivateflags |= pressed;
Refreshdrawablestate ();
if ((Mviewflags & long_clickable) = = long_clickable) {
postcheckforlongclick ();
}
break;
Case MOTIONEVENT.ACTION_UP:
if ((Mprivateflags & pressed)!= 0) {
Boolean focustaken = false;
if (isfocusable () && isfocusableintouchmode () &&!isfocused ()) {
Focustaken = Requestfocus ();
}
if (!mhasperformedlongpress) {
if (mpendingcheckforlongpress!= null) {
removecallbacks ( mpendingcheckforlongpress);
}
if (!focustaken) {
performclick ();
}
}
... Break
As you can see, the trigger for the click Occurs after the system captures the ACTION_UP and is executed by PerformClick (), and PerformClick calls the OnClick () method of the previously registered listener:
public boolean PerformClick () {
...
if (Monclicklistener!= null) {
playsoundeffect (soundeffectconstants.click);
Monclicklistener.onclick (this);
return true;
}
return false;
}
The trigger of the Longclick is started from Action_down, and is done by the Postcheckforlongclick () method:
private void Postcheckforlongclick () {
mhasperformedlongpress = false;
if (mpendingcheckforlongpress = = null) {
mpendingcheckforlongpress = new checkforlongpress ();
}
Mpendingcheckforlongpress.rememberwindowattachcount ();
Postdelayed (Mpendingcheckforlongpress, Viewconfiguration.getlongpresstimeout ());
}
As you can see, after the Action_down event is captured, the system starts to trigger a postdelayed operation that triggers 500ms,500ms thread execution after the delay time is checkforlongpress on Eclair2.1:
Class Checkforlongpress implements Runnable {
...
public void Run () {
if (ispressed () && (mparent!= null)
&& Moriginalwindowattachcount = = Mwindow Attachcount) {
if (Performlongclick ()) {
mhasperformedlongpress = true;
}
}} ..
}
If all the conditions are met, Performlongclick () is executed in checkforlongpress, and Onlongclick () is invoked in this method:
public Boolean Performlongclick () {
...
if (Monlongclicklistener!= null) {
handled = Monlongclicklistener.onlongclick (view.this);
}
..
}
&NBSP;&NBSP
The onclick () and Onlongclick () methods can be seen from the implementation to be finally determined by the Action_down and ACTION_UP events after they are captured, That is, if we monitor or overwrite the onclick (), Onlongclick () and Ontouchevent () methods in an activity or view, it does not mean that only one of them will occur.