Activity
There are two main methods related to event delivery in an Activity, dispatchTouchEvent() and onTouchEvent(). Event delivery starts with the dispatchTouchEvent() method of the Activity.
Event distribution
Event distribution method in Activity: dispatchtouchevent (), and its source code is as follows:
//Event distribution public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { //Empty method onUserInteraction(); } if (getWindow().superDispatchTouchEvent(ev)) { return true; } //The onTouchEvent() method returns false by default return onTouchEvent(ev); }
Obviously, only action is processed in the above code_ Down event, description action_ The down event will trigger the event distribution. Then, the superDispatchTouchEvent(ev) method of Window class is called, which is an abstract method. When this method is called, the methods in the specific subclass will be called. The specific subclass of Window class is PhoneWindow class. The specific implementation of superDispatchTouchEvent(ev) method is as follows:
//Abstract methods in Window class public abstract boolean superDispatchTouchEvent(MotionEvent event); //Concrete implementation of superDispatchTouchEvent() method in PhoneWindow subclass @Override public boolean superDispatchTouchEvent(MotionEvent event) { return mDecor.superDispatchTouchEvent(event); }
Obviously, there is a call to mDecor Superdispatchtouchevent (event), mDecor is a phonewindow Decorview object, which is also the top-level view of the window. It is the root view of a real activity. It inherits FrameLayout through super Dispatchtouchevent will send touchevent to the child views of each activity, that is, we are in activity The view set when setContentView is set in oncreat method. The code reference is as follows:
//DecorView class declaration private final class DecorView extends FrameLayout implements RootViewSurfaceTaker { ... public boolean superDispatchTouchEvent(MotionEvent event) { //Here, the dispatchTouchEvent method in FrameLayout is called again return super.dispatchTouchEvent(event); } ... }
Since the dispatchTouchEvent(event) method is not overridden in FrameLayout, we need the parent class of FrameLayout, that is, the implementation of this method in ViewGroup. This method is used to distribute events. Here, the specific event distribution process needs to be studied.
event processing
The event handling method in Activity: onTouchEvent(), and its source code is as follows:
//Event handling. false is returned by default public boolean onTouchEvent(MotionEvent event) { if (mWindow.shouldCloseOnTouch(this, event)) { finish(); return true; } //false is returned by default return false; }
For the onTouchEvent() method, the event is passed to the parent control. Even if false is returned, the event is equivalent to being consumed.
Note: when an Activity distributes events, only return super When dispatchtouchevent (EV), the event continues to pass down. If true or false is returned, the event is consumed, that is, the propagation of the event is terminated.
ViewGroup
There are three main methods related to event delivery in ViewGroup: dispatchTouchEvent(), onInterceptTouchEvent() and onTouchEvent(), as follows:
Event distribution
The event distribution method in ViewGroup: dispatchTouchEvent(), and its source code is as follows:
@Override public boolean dispatchTouchEvent(MotionEvent ev) { ... //The dispatchTouchEvent() method returns false by default boolean handled = false; //Determine whether to intercept the distribution of events to the method onInterceptTouchEvent(ev); ... //Cancelled and intercepted are false by default if (!canceled && !intercepted) { ... //This method passes the event to the child View dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) { ... } return handled; }
The function of this method is to traverse the child views in the View Group and hand over the event (ACTION_DOWN) to the child views for processing. It mainly calls oninterceptotouchevent() and dispatchTransformedTouchEvent() methods. Oninterceptotouchevent() returns false by default. The following is the main source code of dispatchTransformedTouchEvent() method:
private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel, View child, int desiredPointerIdBits){ ... if (child == null) { handled = super.dispatchTouchEvent(event); } else { //Event distribution for child views handled = child.dispatchTouchEvent(event); } ... return handled; }
Obviously, the dispatchTransformedTouchEvent() method is mainly used to distribute the events of the child View. If there is no child View, the dispatchTouchEvent(event) method of the parent View will be called.
Event interception
The event distribution method onInterceptTouchEvent() in ViewGroup has the following source code:
public boolean onInterceptTouchEvent(MotionEvent ev) { ... //false is returned by default return false; }
This method returns false by default, which means that event distribution to child views is not intercepted. This method is called in the dispatchTouchEvent() method of View Group.
event processing
The ViewGroup does not have its own onTouchEvent() event handling method. The ViewGroup inherits the View, and its event handling method is the View's event handling method. Its methods are as follows:
public boolean onTouchEvent(MotionEvent event) { ... //false is returned by default return false; }
This method processes related events. If true is returned, it means that the event is processed. The specific usage will be recorded below.
View
There are two main methods related to event distribution in View: dispatchTouchEvent() and onTouchEvent() methods, as follows: