For a view control on the screen, how does Android differentiate whether an ontouchevent, onclick, or onlongclick event should be triggered?
In Android, a user operation can be processed by different views in order, and a UI operation that completely responds to the user is called a consume event ), in what order does Android send events? Under what circumstances is the event considered to have been consumed?
Figuring out these problems is very important for coding code that can correctly respond to UI operations, especially when different views on the screen need to make different responses to this UI operation, A typical example is that you place a widget on the desktop. When you perform various operations on the widget, the desktop sometimes responds to the user's operations and sometimes ignores them. Only by clarifying the event triggering and transfer mechanisms can the UI control still correctly respond to user operations when the interface layout is very complex.
1. ontouchevent
The three most common events to be processed in ontouchevent are: action_down, action_move, and action_up.
These three events identify the most basic user touch screen operations and have a clear meaning. Although they are used every day, please note that the importance of the action_down event as the starting event is greater than action_move and action_up. If action_move or action_up occurs, therefore, action_down must have occurred.
Some interaction mechanisms implemented based on the understanding of different importance can be seen from the android source code, which is also explicitly mentioned in the SDK, for example, in the onintercepttouchevent method of viewgroup, if true is returned in the action_down event, subsequent events are sent directly to ontouchevent instead of onintercepttouchevent.
2. onclick, onlongclick, and ontouchevent
I have read a Post saying that if ontouchevent is processed in the view, you don't need to process onclick any more, because Android only triggers one of the methods. This understanding is not correct. For a view, the user completes a touch operation. Obviously, the signal obtained from the sensor is that the finger presses and raises two operations. We can think of it as a click, it can also be understood as the occurrence of action_down and action_up, so how does Android understand and process it?
In Android, onclick and onlongclick triggers are related to action_down and action_up. In time sequence, if onclick, onlongclick, and ontouchevent are overwritten in a view, ontouchevent is the first event to capture the action_down and action_up events. Second, onclick or onlongclick can be triggered. 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 ){
Optional mclick ();
}
}
...
Break;
As you can see, the click trigger occurs after the system captures action_up and is executed by the listener mclick (). The onclick () method of the previously registered listener is called in the listener mclick:
Public Boolean initialize mclick (){
...
If (monclicklistener! = NULL ){
Playsoundeffect (soundeffectconstants. Click );
Monclicklistener. onclick (this );
Return true;
}
Return false;
}
The longclick trigger starts from action_down and is completed by the postcheckforlongclick () method:
Private void postcheckforlongclick (){
Mhasperformedlongpress = false;
If (mpendingcheckforlongpress = NULL ){
Mpendingcheckforlongpress = new checkforlongpress ();
}
Mpendingcheckforlongpress. remember#wattachcount ();
Postdelayed (mpendingcheckforlongpress, viewconfiguration. getlongpresstimeout ());
}
As you can see, after the action_down event is captured, the system will start to trigger a postdelayed operation. The delay time is 500 ms on eclair2.1, and MS will trigger the execution of the checkforlongpress thread:
Class checkforlongpress implements runnable {
...
Public void run (){
If (ispressed () & (mparent! = NULL)
& Moriginalwindowattachcount = m?wattachcount ){
If (descrimlongclick ()){
Mhasperformedlongpress = true;
}
}
}
...
}
If all the conditions are met, execute commit mlongclick () in checkforlongpress. In this method, onlongclick () is called ():
Public Boolean initialize mlongclick (){
...
If (monlongclicklistener! = NULL ){
Handled = monlongclicklistener. onlongclick (view. This );
}
...
}
From the implementation, we can see that the onclick () and onlongclick () methods are captured by the action_down and action_up events and finally determined whether to trigger according to various situations, that is to say, if we listen to or overwrite the onclick (), onlongclick () and ontouchevent () methods in an activity or view at the same time, it does not mean that only one of them will happen.
Below is a log of the basic sequence of onclick triggering:
04-05 05:57:47. 123: Debug/tsactivity (209): ontouch action_down
04-05 05:57:47. 263: Debug/tsactivity (209): ontouch action_up
04-05 05:57:47. 323: Debug/tsactivity (209): onclick
It can be seen that it occurs in the order of action_down-> action_up-> onclick.
Below is a log of the basic sequence triggered by onlongclick:
04-05 06:00:04. 133: Debug/tsactivity (248): ontouch action_down
04-05 06:00:04. 642: Debug/tsactivity (248): onlongclick
04-05 06:00:05. 083: Debug/tsactivity (248): ontouch action_up
It can be seen that the onlongclick will be triggered after a certain period of time, and then the action_up will occur when you raise your hand.
3. Can onclick and onlongclick occur simultaneously?
To solve this problem, you only need to understand the so-called consumption (consume) concept of event processing by Android, operations of a user are passed to different view controls and different listening methods of the same control for processing, if true is returned for any method that receives and processes the event, the event is completely processed, other views or listening methods will not have a chance to process the event any more.
Onlongclick occurs in a separate thread and before action_up, while onclick occurs after action_up, therefore, onlongclick and onclick may occur in the same touch operation. Is that incredible? Therefore, it is very important to tell the system that "I have completely processed (consumed) the user's operation. For example, if we return true at the end of the onlongclick () method, The onclick event will not be triggered.
The following log shows the basic sequence of a touch operation when the onlongclick () method returns false:
04-05 06:00:53. 023: Debug/tsactivity (277): ontouch action_down
04-05 06:00:53. 533: Debug/tsactivity (277): onlongclick
04-05 06:00:55. 603: Debug/tsactivity (277): ontouch action_up
04-05 06:00:55. 663: Debug/tsactivity (277): onclick
We can see that the onclick () method is still triggered after action_up.
[Reference from http://blog.csdn.net/ddna/article/details/5451722]