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

US version of Mondeo under investigation by safety regulator

According to foreign media reports recently, Ford...

I never thought that air conditioning could cause heat stroke?!

Recently, there is a rumor about air conditioners...

How's the battery life on the new iPhone 6? Disappointing

The iPhone 6 and iPhone 6 Plus have bigger, brigh...

Aiming at Apple, LeEco aims to capture the US market

After the news that LeEco's mobile phone Sili...

My child’s teeth are corroded even though he never drinks carbonated drinks?

Many parents know that carbonated drinks can corr...

2022, new consumer brand marketing strategy!

Only by binding yourself to a growing ecosystem a...

How to build a user operation system?

As the product size grows, the number and types o...