preface

Before the popularity of smart phones, people relied on keyboards to interact with mobile phones, but the functions realized were limited and it was very inconvenient to use. After the emergence of smart phones, the interaction between people and mobile phones has become diverse, and many functions can be realized just by clicking and sliding. Especially the trend of the development of the mobile phone is now even to remove only the virtual keyboard, complete with hand gestures to control cell phones, now many phones slide to the left is exit pages, for example, now imagine a scene, is you reading a novel page also needs to slide to the left, if you slide it out of the left, it’s definitely not what you want, so how to implement in reading a novel when not quit? This brings us to today’s topic, event distribution, and hopefully by the end of this article you will have the answer in your mind.

directory

Classification of events

Events are objects to which events are distributed, that is, interactions with the screen. There are four types of eventsNote: In general, the move event will be triggered multiple times in a slide, such as pressing at point B, sliding to point C, and then leaving. Multiple move events will occur during the slide instead of one.

Correlation function

Before we talk about correlation functions, let’s look at who events are passed to. The general structure of an App may be as shown in the following figure. An Activity contains a ViewGroup and a ViewGroup contains a View. Events are passed between the Activity, ViewGroup, and View.The relevant functions are shown belowWhere dispatchTouchEvent is called when an event comes in and is used to distribute the event. OnTouchEvent handles events. OnInterceptTouchEvent is a ViewGroup specific event. If it intercepts an event, the event will not flow to the view.

The process of event distribution

The above three functions are not intuitive enough to understand the process, so let’s use an example to illustrate the process. An Activity has a LinearLayout as a ViewGroup, and inside the ViewGroup is a WebView. The layout file is as follows, because I have to rewrite three functions, So the LinearLayout and the WebView have been rewritten which is LL and TWebView.

<? The XML version = "1.0" encoding = "utf-8"? > <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <io.appetizer.touch.LL android:id="@+id/ll" android:layout_width="match_parent" android:layout_height="match_parent"> <io.appetizer.touch.TWebView android:layout_width="match_parent" android:layout_height="match_parent"> </io.appetizer.touch.TWebView> </io.appetizer.touch.LL> </androidx.constraintlayout.widget.ConstraintLayout>Copy the code

In the case that nothing is handled, the event is passed as follows, rightFrom this picture we can see two things:

(1) The order of event delivery is Activity -> ViewGroup -> View, in the case of no interception event processing order is View -> ViewGroup -> Activity.

(2) If ACTION_DOWN, ACTION_MOVE and ACTION_UP are considered as a whole, when ACTION_DOWN is passed on and the result is not responded or consumed, the onTouchEvent of the Activity is returned, the subsequent events will not be passed down.

The experiment of a

Note: All three functions return Boolean values

When we make the OnInterceptTouchEvent of the ViewGroup return false, the result is as follows

When we make the OnInterceptTouchEvent return true, the result is as followsAs you can see, when OnInterceptTouchEvent returns true, the ViewGroup intercepts the event and the event does not flow to the View.

Experiment 2

From Experiment 1, we can see that the ViewGroup intercepts the event, but the ViewGroup does not consume the event, and the event eventually flows back to the Activity. So how do we consume the event in the ViewGroup, and we don’t want the Activity to react to the event, otherwise it might cause sliding conflicts? As we discussed at the beginning of the conflict between page-turning and exiting the App, if the event flows back into the Activity, it may exit directly, which is not what we want. To consume an event, we typically add a setOnTouchListener to the control and return true to indicate that the event is consumed and not passed back.

LinearLayout ll = findViewById(R.id.ll); ll.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) {log. d("TEST", "ViewGroup consumption event "); return true; }});Copy the code

The result is as follows:We can see from the figure that the event is consumed in the ViewGroup without being passed back to the Activity.

The experiment of three

In experiment 2, we saw how GroupView intercepts and consumes events. In most cases, the process is the same. Set setOnTouchListener to true. Also need to add a function requestDisallowInterceptTouchEvent (Boolean disallowIntercept) request parent don’t intercept events, the parameter is true, won’t intercept, the code is as follows

TWebView tWebView = findViewById(R.id.tWebView); tWebView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { v.getParent().requestDisallowInterceptTouchEvent(true); Log.d("TEST TOUCH", "View consumption event "); return true; }});Copy the code

The result is as followsAs shown, the event is consumed by the View and not sent back.

The last

If there is a mistake, welcome to correct, if you feel that the writing is ok, like is the biggest support.