Android touch events (notes)

Android touch events (notes)

There are not many articles with similar titles on the Internet. I once thought I had mastered it, but I found problems when I used it recently. Then I realized that I didn’t really understand it before, so I wrote this note.

The logic of event dispatching depends on ACTION_DOWN

Also note that the process of ACTION_MOVE and ACTION_UP is not exactly the same as ACTION_DOWN

The following picture is the processing logic diagram of ACTION_DOWN gesture

In the past, my concept of gesture processing only stopped here, and I also mistakenly thought that the logic of ACTION_MOVE and ACTION_UP should be like this (from the situation around me, I am not the only one who thinks so).

Here we take ViewGroup as an example to summarize (note that for ease of understanding, I only analyzed ViewGroup, activity and View are slightly different)

dispatchTouchEvent

Can consume events

If true is returned, the event is consumed by itself and the transmission is terminated;

If false is returned, the event is not consumed and is handled by the parent's onTouchEvent;

If super is returned, the event is not consumed and the event is dispatched to onInterceptTouchEvent for processing.

onInterceptTouchEvent

Unable to consume events

If true is returned, the event is dispatched to its own onTouchEvent for processing;

If false/super is returned, the event is dispatched to the child's dispatchTouchEvent for processing;

onTouchEvent

Can consume events

If true is returned, the event is consumed by itself and the transmission is terminated;

If false/super is returned, the event is dispatched to the parent's onTouchEvent for processing;

As you can see, there are only two places where the event is finally consumed, when dispatchTouchEvent and onTouchEvent return true, and when they return false, the event is handed over to the upper-level onTouchEvent for processing. One of them is before onInterceptTouchEvent, and the other is after onInterceptTouchEvent. OnInterceptTouchEvent just diverts the event, thus forming this Android event transfer diagram.

About ACTION_MOVE and ACTION_UP

In summary, when all return to super by default, the onTouchEvent of a layer that returns true will receive ACTION_MOVE and ACTION_UP, and the dispatchTouchEvent and onInterceptTouchEvent of the same level and above can receive ACTION_MOVE and ACTION_UP, as shown in the following figure

From the above figure, we can see that there can only be one onTouchEvent that can receive ACTION_MOVE and ACTION_UP in the end. Even if your upper-level onInterceptTouchEvent returns true for ACTION_MOVE, it will only distribute the ACTION_MOVE event to the upper layer, and the child View will not receive the ACTION_MOVE event. In other words, when a View returns true in ACTION_DOWN in onTouchEvent, its ACTION_MOVE and ACTION_UP events are actually the same no matter what results are returned, because the ACTION_MOVE event has been distributed here, even if it returns false, the upper layer will not receive it! (This concept is completely inconsistent with my previous three views. Of course, you can refute me if you think it is wrong. I didn’t believe it at the beginning.)

Use of requestDisallowInterceptTouchEvent

In gesture processing, we can also use the requestDisallowInterceptTouchEvent method to reject the interception of the event by onInterceptTouchEvent.

For some GroupView, it will intercept the ACTION_MOVE event in the onInterceptTouchEvent event, such as ListView, ScrollView, etc. At this time, the childView cannot get the ACTION_MOVE event (the common ScrollView nested ViewPager, ViewPager cannot slide). In addition to overriding the onInterceptTouchEvent method of GroupView, we can also overwrite the dispatchTouchEvent method of ChildView to solve it.

First of all, no matter how powerful GroupView is, by default, it will not return true in the ACTION_DOWN event of onInterceptTouchEvent, because this will result in the childView having no chance to get the gesture at all. Then, the childView can receive the ACTION_DOWN event in the dispatchTouchEvent method. At this time, we call the parent's requestDisallowInterceptTouchEvent method and set it to true to notify GroupView not to intercept my event. Then, the ACTION_MOVE event that should have been intercepted by GroupView will bypass the onInterceptTouchEvent method of GroupView and be directly passed down to the dispatchTouchEvent of childView.

It is worth noting that in dispatchTouchEvent, getParent().requestDisallowInterceptTouchEvent(false) and return false have different effects.

When GroupView.requestDisallowInterceptTouchEvent(true) is called, the onTouchEvent method will not receive any events, so if you return false in the dispatchTouchEvent method of ChildView, the effect is actually the same as return true. Only when GroupView.requestDisallowInterceptTouchEvent(false) is called, the gesture will be handed over to GroupView for processing again.

So, at this time, if you want to consume only a certain type of ACTION_MOVE event (such as horizontal sliding) in ChildView, you need to call getParent().requestDisallowInterceptTouchEvent(false) instead of return false, as shown in the following figure:

In addition, many people on the Internet call getParent().requestDisallowInterceptTouchEvent(false) when ACTION_UP, but this is not necessary, because when receiving ACTION_DOWN, GroupView will set requestDisallowInterceptTouchEvent to false by default.

<<:  Android obfuscation from entry to mastery

>>:  Android's four major components Service

Recommend

The process of building a high-conversion information flow account!

When it comes to bidding account structure, every...

Kaola.com Product Analysis

Kaola.com (formerly known as NetEase Kaola) is an...

81% screen-to-body ratio: Sharp AQUOS Phone hands-on

For fans of Japanese mobile phones, the AQUOS Phon...

iOS 9 public beta launches smart prediction/power saving mode

[[139793]] In the early morning of July 10th, Bei...

There is a kind of romance in the universe, I am your companion star

Alien planetary system has a Jupiter world 99 tim...

The photos of "red fire ants" you see are probably wrong...

A bite from a red fire ant can cause severe pain ...

What is the lowest price per gram of good Cordyceps sinensis?

As a precious tonic medicine, Cordyceps sinensis ...

Zhihu’s operational strategy

I recently updated the Zhihu app to 6.46.0., and ...