PS: Don't be too anxious, it is most important to solidly enrich yourself.
The previous article mainly provided a basic overview of the event methods in Activity, ViewGroup, and View. The following will summarize the event propagation in Android through examples.
- Default event dispatch process
- Event dispatch
- Event handling
- Event interception
- Summary
Default event dispatch process#
The normal flow of Android event dispatch, that is, how events are dispatched by default. First, customize a ViewGroup and a View, such as inheriting LinearLayout to create a custom ViewGroup called MLinearLayout, and inheriting TextView to create a custom View called MTextView. Then, override the event methods related to event dispatch in each of them. The Activity also overrides its own event methods. Observe the normal event dispatch process through logs. The layout is shown in the following figure:
By triggering the onTouch event of MTextView, all the event dispatch methods are handled by default. The execution process is shown in the following figure:
Obviously, the starting point of event dispatch is the dispatchTouchEvent() method of the Activity. Then, it is distributed to the ViewGroup through a series of action events. Specifically, it calls the dispatchTouchEvent() method of the ViewGroup. The onInterceptTouchEvent() method of the ViewGroup returns false by default, which means that the event is not intercepted and is passed to the child View (the ViewGroup is also a child View, such as MRelativeLayout) until it reaches the innermost child View.
Of course, when the event is dispatched to the child View, it calls the dispatchTouchEvent() method of the child View. The event dispatch method internally calls the onTouchEvent() method. The onTouchEvent() method returns false by default, indicating that the View does not consume the event. If it returns true, it means that the event is consumed. The following is the default event dispatch process drawn based on the above execution results, as shown in the following figure:
Through the above verification, at least we can understand the execution order of various event-related methods.
Event dispatch#
The dispatchTouchEvent() method is responsible for event dispatching, determining whether the current event is consumed by itself or continues to be dispatched to the child View. Returning true means that the event has been consumed, and subsequent events such as ACTION_MOVE and ACTION_UP will continue to be executed. Returning false means that the event continues to be dispatched to the child View. If the child View is a ViewGroup, it will first dispatch the event to the onInterceptTouchEvent() method to determine whether to intercept the event. According to the above example, if the dispatchTouchEvent() method of MRelativeLayout returns true, the event is consumed and a series of subsequent events are accepted. The log screenshot is shown in the following figure:
Obviously, when the dispatchTouchEvent() method of MRelativeLayout returns true, the event does not propagate downwards. In order to observe the execution of each event method more clearly, specific events (such as ACTION_DOWN) are not output in the log. Therefore, when the dispatchTouchEvent() method returns true, it means that the event has been consumed.
Event interception#
The onInterceptTouchEvent() method is responsible for event interception. Its return value determines whether to intercept the current event. Returning true means intercepting the current event, otherwise, the event is not intercepted. The default implementation continues to call the dispatchTouchEvent() method of the child View for event dispatching. According to the above example, if the onInterceptTouchEvent() method of MRelativeLayout is set to return true, the current event is intercepted and the event does not propagate downwards. The log screenshot is shown in the following figure:
After the event is intercepted, it needs to be handled. Of course, event handling is the responsibility of the onTouchEvent() method. The onTouchEvent() method can handle the event or not. If the onTouchEvent() method returns true, it means that the event is handled. If it returns false, the event is handed over to the onTouchEvent() method of the parent View for handling. In the case shown in the figure, MRelativeLayout intercepts the event but does not handle it, and finally, it is handled by the Activity.
Event handling#
The onTouchEvent() method is responsible for event handling. Its return value determines whether the View consumes the event. Returning true means that the current View consumes the event, and returning false means that the View does not consume the event, and the event is propagated to the parent View. According to the above example, if the onTouchEvent() method of MRelativeLayout is set to return true, the log screenshot is shown in the following figure:
Several ACTION_MOVE events are omitted in the screenshot above. After a View successfully intercepts an event, a series of events after ACTION_DOWN will be directly handled by that View.
Summary#
- Event dispatch is performed from the parent View to the child View. During the dispatch process, if the event is not intercepted and handled, when it reaches the deepest level View, it will be passed back to the parent View and finally handled by the Activity. Subsequent events will not be received. If a View intercepts an event and handles it, then the event is handled by the onTouchEvent() method of the View that intercepts the event. If a View intercepts an event and does not handle it, the event stops being dispatched to the child View and is then handled by the onTouchEvent() method of the parent View.
- After an event is intercepted, it needs to be handled. The handling of the event is mainly done by the onTouchEvent() method of the View that intercepts the event or the onTouchEvent() method of its parent View, depending on the return value of the corresponding onTouchEvent() method.
- The handling of the event is done by the onTouchEvent() method. Returning true means that the event is handled, and returning false means that the event is not handled and continues to be passed upwards until it is handled.