Transfer and processing of touch events of Android controls
Understanding the touch event transfer and processing of Android controls is of great significance for us to resolve conflicts between custom controls and touch events in our daily development. The following methods are used to pass and process touch events of Android controls.
I. methods related to touch events
Boolean dispatchTouchEvent (MotionEvent ev );
|
Whether to distribute the event to the following View when a touch event is received Returns true: Distribution of touch events False is returned. If the event is not distributed, the following View will not receive the touch event. |
Boolean onInterceptTouchEvent (MotionEvent ev );
|
Whether to intercept a touch event Returns true: intercept. The onTouchEvent method is called to process the event. False: no interception is returned. The event continues to be passed to the sub-View.
|
Boolean onTouchEvent (MotionEvent ev );
|
Event Response? Returns true: Response Return false: No Response
|
Boolean onTouch (View v, MotionEvent event );
|
Whether to respond to the event. When View calls the setOnTouchListener method and sets the touch listener, it first calls the onTouch method in response to the event. Returns true: Response, the onTouchEvent method is not executed False: no response is returned, and the onTouchEvent method is called.
|
Void requestDisallowInterceptTouchEvent (boolean disallowIntercept );
|
Request whether the parent control does not intercept events Returns true. onInterceptTouchEvent of the parent control is not allowed. False: Call allowed |
Ii. classes with these methods
Parent class |
Subclass |
Methods available |
Activity |
Activity |
DispatchTouchEvent and onTouchEvent |
ViewGroup |
RelativeLayout, LinearLayout... |
DispatchTouchEvent, onTouchEvent, onInterceptTouchEvent, requestDisallowInterceptTouchEvent |
View |
Button, TextView... |
DispatchTouchEvent and onTouchEvent |
Iii. event handling rules
Touch events are distributed from Activity distribution (distribution only, not processed yet) to parent controls. Parent controls determine whether to intercept events. If event blocking is not performed, they are distributed to child controls, and then distribute them all the time. On the contrary, the sub-control processes the event first. If the sub-control does not process the event, it is handed over to the parent Control for processing until the control processes the touch event, event Processing ends here.
1. when you touch the screen, three touch events (ACTION_DOWN, ACTION_MOVE, and ACTION_UP) are generated from the press to the move, and finally to the lift. The event is first transmitted to the Activity, and then the Activity calls the dispatch event Method dispatchTouchEvent, if true is returned, the event is sent to the first parent control of the Activity.
2. after the parent control obtains the event, it also calls the dispatch event Method dispatchTouchEvent. If true is returned, it continues to call the interception method onInterceptTouchEvent. If true is returned, the parent control intercepts the event, and call the onTouchEvent method of the parent control. The following child control will no longer respond to the onTouchEvent and onTouch methods.
3. after obtaining the event, the Child control determines whether OnTouchListener is set. If so, the onTouch method of OnTouchListener is called. If true is returned, the onTouchEvent method is skipped after the event is processed, otherwise, the onTouchEvent method is called. When the onTouchEvent method returns true, the event processing ends, and the parent control above will no longer call the onTouchEvent method.
4. if a widget responds to the ACTION_DOWN event, the subsequent ACTION_MOVE and ACTION_UP events are directly handled by the widget, unless its parent widget intercepts subsequent events, however, when processing the ACTION_DOWN event, you can call requestDisallowInterceptTouchEvent to disable the interception of the parent control. If the control does not process the ACTION_DOWN event, subsequent events will not be uploaded to the control. When the current ACTION_DOWN event is generated, it will still be passed to the View.
4. Here is a demonstration.
Define MainActivity, ParentView, ChildView, OnTouchListener
MainActivity --> mom
ParentView --> Dad
ChildView --> me
OnTouchListener --> wife
Event --> Apple (three apples at a time, simulating ACITON_DWON, ACTION_MOVE, and ACTION_UP events)
In this case, a family eats apple and simulates the processing of touch events.
Mom MainActivity source code:
Package com. test. activity; import com. example. javawebtest. r; import android. OS. bundle; import android. util. log; import android. view. motionEvent; import android. app. activity; public class MainActivity extends Activity {@ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main) ;}@ Override public boolean onTouchEvent (MotionEve Nt event) {// TODO Auto-generated method stub boolean eat = false; Log. I (getClass (). getSimpleName (), "mom" + (eat? "Eat apple": "did not eat, threw"); return eat ;}@ Override public boolean dispatchTouchEvent (MotionEvent ev) {// TODO Auto-generated method stub Log. I (getClass (). getSimpleName (), "Mom wants to give Apple to Dad"); return super. dispatchTouchEvent (ev );}}
Dad ParentView source code:
Package com. test. view; import android. content. context; import android. util. attributeSet; import android. util. log; import android. view. motionEvent; import android. widget. relativeLayout; public class ParentView extends RelativeLayout {public ParentView (Context context, AttributeSet attrs) {super (context, attrs ); // TODO Auto-generated constructor stub} @ Overridepublic boolean dispatchTouchEvent (MotionEvent e V) {// TODO Auto-generated method stubLog. I (getClass (). getSimpleName (), "Dad wants to give me an apple"); return super. dispatchTouchEvent (ev) ;}@ Overridepublic boolean onInterceptTouchEvent (MotionEvent ev) {// TODO Auto-generated method stubboolean intercept = false; Log. I (getClass (). getSimpleName (), "Dad" + (intercept? "Want to eat": "Don't want to eat") + "apple"); return intercept? True: super. onInterceptTouchEvent (ev) ;}@ Overridepublic boolean onTouchEvent (MotionEvent event) {// TODO Auto-generated method stubboolean eat = false; Log. I (getClass (). getSimpleName (), "Dad" + (eat? "Eat apple": "did not eat, gave Mom"); return eat ;}}
Source code of my ChildView and wife OnTouchListener:
Package com. test. view; import android. content. context; import android. util. attributeSet; import android. util. log; import android. view. motionEvent; import android. view. view; import android. view. view. onTouchListener; public class ChildView extends View implements OnTouchListener {public ChildView (Context context, AttributeSet attrs) {super (context, attrs); // TODO Auto-generated constructor stubsetOnTouchLis Tener (this) ;}@ Overridepublic boolean onTouchEvent (MotionEvent event) {// TODO Auto-generated method stubboolean eat = false; Log. I (getClass (). getSimpleName (), "I" + (eat? "Eat an apple": "did not eat an apple, gave it to Dad"); return eat ;}@ Overridepublic boolean onTouch (View v, MotionEvent event) {// TODO Auto-generated method stubboolean eat = false; Log. I (getClass (). getSimpleName (), "wife" + (eat? "I ate an apple": "I didn't eat an apple. I gave it to me"); return eat ;}}
Scenario 1: no one eats apple, as shown in figure
At the beginning, the first Apple was always down, and no one had eaten it. Later, my mother knew that we didn't like Apple, and the second and third Apple didn't send it to us, so she threw it away...
<喎?"http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHA + IAogs6G + sLb + 5E + pgltzybzcm9 "http://www.2cto.com/uploadfile/Collfiles/20141221/2014122109040324.png" alt = "\">
I have eaten apple, but I have to ask my wife before each meal. If my wife eats it, I cannot eat it...
Scenario 3: dad snatched apple and set the intercept of onInterceptTouchEvent to true.
As a result, Apple was eaten by Dad and there was no such thing as me...