Android event distribution interception (onInterceptTouchEvent dispatchTouchEvent onTouchEvent)

Source: Internet
Author: User

Android event distribution interception (onInterceptTouchEvent dispatchTouchEvent onTouchEvent)

There are only two protagonists in Touch event distribution: ViewGroup and View. The Touch event of an Activity is actually a Touch event that calls its internal ViewGroup and can be processed as a ViewGroup directly. In ViewGroup, ViewGroup can also be in other viewgroups. In this case, the internal ViewGroup is used as View for analysis.

 

There are three events related to ViewGroup: onInterceptTouchEvent, dispatchTouchEvent, and onTouchEvent.

There are only two View-related events: dispatchTouchEvent and onTouchEvent.

First, analyze the processing process of ViewGroup. First, we need to have a structure model concept: ViewGroup and View form a tree structure, with the top layer being the ViewGroup of Activity. Below there are several ViewGroup nodes, there are several ViewGroup nodes or View nodes under each node, and so on.

When a Touch event (for example, a Touch event) arrives at the root node, that is, the ViewGroup of Acitivty, it is delivered in sequence, and the process of delivery is implemented by calling the dispatchTouchEvent method of the child View (ViewGroup. To put it simply, ViewGroup traverses the child View it contains and calls the dispatchTouchEvent method of each View. When the child View is a ViewGroup, the dispatchTouchEvent method of the ViwGroup will be called to continue calling the dispatchTouchEvent method of its internal View. In the above example, the message delivery order is as follows: ①-②-⑤-⑥-7-③-④. The dispatchTouchEvent method is only responsible for event distribution. It has a boolean type return value. If the return value is true, sequential delivery is interrupted. In the preceding example, if the return result of the 5th dispatchTouchEvent is true, neither of them will receive this Touch event.

 

It's still code verification. Once it's written

 

 

 

The dispatchTouchEvent of ViewGroup is actually executing the "distribution" work, while the dispatchTouchEvent method of View does not execute the distribution work, or the object it distributes is its own, deciding whether to give the touch event to itself for processing, the processing method is the onTouchEvent event.

 

 

public class Btn extends Button {    public Btn(Context context) {        super(context);    }    public Btn(Context context, AttributeSet attrs) {        super(context, attrs);    }    public Btn(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        Log.i("Btn","dispatchTouchEvent "+ev.getAction()+"");        return super.dispatchTouchEvent(ev);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        Log.i("Btn","onTouchEvent "+event.getAction()+"");        return super.onTouchEvent(event);    }}

 

 


 


Main. xml

 

After the logs are added, click btn to view the execution sequence.

It can be seen that by default, viewgroup will distribute events downward through the dispatchTouchEvent. During the dispatchTouchEvent process, onInterceptTouchEvent is called to check whether the viewgroup intercepts the event.
The onTouchEvent is called when the leaf node view is down and then the onclicklistener is called when the leaf node view is down.

 

Now let's verify the impact of dispatchTouchEvent return values on Event distribution. under normal circumstances, the default dispatchTouchEvent is super. dispatchTouchEvent. return true; the event is no longer passed to the underlying layer. ontouch events should also be consumed by viewing or viewgroup.

Test ONE (btnLinerLayout's dispatchTouchEvent returns false and true respectively)

False:

We can see that the down event stops distributing in btnLinerLayout. (btn dispatchTouchEvent is not executed), the event is first processed by the onTouchEvent of rootLinerLayout and then returned to the superior TestActivity onTouchEvent for processing. the last onTouchEvent is designated as the processing of subsequent events. The up event is directly handled by TestActivity.

One thing I don't understand: After the onTouchEvent of TestActivity is executed, the onclickListener of btn will not be executed. |

True:

 

True means that the event is not passed to the underlying layer as expected. There is no place to consume onTouchEvent... |

At this time, if btnLinerLayout onTouchEvent returns true, the onTouchEvent on the upper layer will be executed in sequence. down and directly handed over to TestActivity.

If btnLinerLayoutonTouchEvent is returned separately, true is returned. if dispatchTouchEvent is super, the result is the same as the default one. the event is finally transmitted to the Btn leaf node for consumption. when the onTouchEvent is executed and down, the event is directly handed over to the onTouchEvent of btn and the onClickLlistener is executed.

 

Summary as long as dispatchTouchEvent is not super, the event transmission will be interrupted. in case of false, the response of the event parent level will respond to onTouchEvent once by default. in addition, the subsequent up event will be handled directly by the top-level target. if it is true, the event will be returned in sequence but will not respond.

 

Test two (the onInterceptTouchEvent of BtnLinerLayout returns true, and the dispatchTouchEvent is super | true | false ):

Normally. onInterceptTouchEvent returns true, which indicates that the event is intercepted by the current viewgroup and consumed.

 

DispatchTouchEvent default super ():

BtnLinerLayout: The execution sequence is dispatchTouchEvent-onInterceptTouchEvent-onTouchEvent. You can handle onTouchEvent by yourself, and pass it to the onTouchEvent of the upper layer in sequence.

 

The value of dispatchTouchEvent is true.

The event has been intercepted and has not been issued. It has reached BtnLinerLayout.

DispatchTouchEvent is false

The event is intercepted. The event is not issued. Currently, no consumption is sent to the parent class onTouchEvent for response. The last event is sent to the top-level TestActicty onTouchEvent for subsequent down events to be directly transferred to TestActivity.

... This is the same as setting dispatchTouchEvent to false onInterceptTouchEvent as the default value. The onTouchEvent is executed by default when it is passed up.

 

We can see from the above two tests

 

OnInterceptTouchEvent is true. The event will be consumed by the current viewgruop to onTouchEvent. By default, the event will be returned to the onTouchEvent of the parent class in sequence. Finally, the event will be sent to the top layer.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.