Home Java javaTutorial Understand the Android Touch event distribution mechanism in 30 minutes

Understand the Android Touch event distribution mechanism in 30 minutes

Jan 16, 2017 pm 04:46 PM

There are only two protagonists in Touch event distribution: ViewGroup and View. The Touch event of Activity actually calls the Touch event of its internal ViewGroup and can be processed directly as a ViewGroup.

View is in a ViewGroup, and a ViewGroup can also be in another ViewGroup. At this time, the internal ViewGroup is analyzed as a View.

There are three related events for ViewGroup: onInterceptTouchEvent, dispatchTouchEvent, and onTouchEvent. There are only two related events for View: dispatchTouchEvent and onTouchEvent.

First analyze the processing flow of ViewGroup: First, there must be a structural model concept: ViewGroup and View form a tree structure. The top level is the ViewGroup of Activity. There are several ViewGroup nodes below. Each node There are several ViewGroup nodes or View nodes underneath, and so on. As shown in the figure:

30分钟搞清楚Android Touch事件分发机制

When a Touch event (touch event as an example) reaches the root node, that is, Active's ViewGroup, it will be delivered in sequence. The delivery process is to call Implemented by the dispatchTouchEvent method of the sub-View (ViewGroup). To put it simply, the ViewGroup traverses the sub-Views it contains and calls the dispatchTouchEvent method of each View. When the sub-View is a ViewGroup, it will continue to call the dispatchTouchEvent method of its internal View by calling the dispatchTouchEvent method of ViwGroup. The message delivery sequence in the above example is as follows: ①-②-⑤-⑥-⑦-③-④. The dispatchTouchEvent method is only responsible for event distribution. It has a boolean return value. When the return value is true, the sequential delivery will be interrupted. In the above example, if the dispatchTouchEvent of ⑤ returns true, then ⑥-⑦-③-④ will not receive this Touch event. Let’s take a simple version of the code to deepen our understanding:

/**
   * ViewGroup
   * @param ev
   * @return
   */
  public boolean dispatchTouchEvent(MotionEvent ev){
    ....//其他处理,在此不管
    View[] views=getChildView();
    for(int i=0;i<views.length;i++){
      //判断下Touch到屏幕上的点在该子View上面 
      if(...){
      if(views[i].dispatchTouchEvent(ev))
       return true;
       }
    }
    ...//其他处理,在此不管
  }
  /**
   * View
   * @param ev
   * @return
   */
  public boolean dispatchTouchEvent(MotionEvent ev){
    ....//其他处理,在此不管
    return false;
  }
Copy after login

It can be seen here that ViewGroup’s dispatchTouchEvent is really performing “distribution” work, while View’s dispatchTouchEvent method does not perform distribution work, or it distributes The object is itself, deciding whether to hand over the touch event to itself, and the method of processing is the onTouchEvent event. In fact, the code actually executed by the dispatchTouchEvent method of the sub-View is like this

/**
   * View
   * @param ev
   * @return
   */
  public boolean dispatchTouchEvent(MotionEvent ev){
    ....//其他处理,在此不管
    return onTouchEvent(event);
  }
Copy after login

Under normal circumstances, We should not override the dispatchTouchEvent method in a normal View because it does not perform distribution logic. When the Touch event reaches the View, all we have to do is handle it in the onTouchEvent event.

So, when is the onTouchEvent event of ViewGroup processed? When all sub-Views of the ViewGroup return false, the onTouchEvent event will be executed. Since ViewGroup inherits from View, it actually executes the onTouchEvent event by calling the View's dispatchTouchEvent method.

From the current situation, it seems that as long as we return false to all onTouchEvents, we can ensure that all sub-controls respond to this Touch event. But it must be noted that the Touch event here is limited to the Action_Down event, that is, the touch press event, while Aciton_UP and Action_MOVE will not be executed. In fact, a complete Touch event should consist of a Down, an Up and several Moves. Down mode is distributed through dispatchTouchEvent. The purpose of distribution is to find the View that really needs to handle the complete Touch request. When the onTouchEvent event of a View or ViewGroup returns true, it means that it is the View that actually wants to handle this request, and subsequent Aciton_UP and Action_MOVE will be handled by it. When the onTouchEvent of all child Views returns false, this Touch request is handled by the root ViewGroup, that is, the Activity itself.

Look at the improved dispatchTouchEvent method of ViewGroup

View mTarget=null;//保存捕获Touch事件处理的View
  public boolean dispatchTouchEvent(MotionEvent ev) {
 
    //....其他处理,在此不管
     
    if(ev.getAction()==KeyEvent.ACTION_DOWN){
      //每次Down事件,都置为Null
 
      if(!onInterceptTouchEvent()){
      mTarget=null;
      View[] views=getChildView();
      for(int i=0;i<views.length;i++){
        if(views[i].dispatchTouchEvent(ev))
          mTarget=views[i];
          return true;
      }
     }
    }
    //当子View没有捕获down事件时,ViewGroup自身处理。这里处理的Touch事件包含Down、Up和Move
    if(mTarget==null){
      return super.dispatchTouchEvent(ev);
    }
    //...其他处理,在此不管
    if(onInterceptTouchEvent()){
     //...其他处理,在此不管  
     }
//这一步在Action_Down中是不会执行到的,只有Move和UP才会执行到。
    return mTarget.dispatchTouchEvent(ev);
 
  }
Copy after login

ViewGroup also has an onInterceptTouchEvent. You can tell from the name that this is an interception event. This interception event needs to be explained in two situations:

1. If we return true in the onInterceptTouchEvent of a ViewGroup and the Action is Down for the Touch event, it means that all the operations issued by the ViewGroup will be Intercept it. In this case, mTarget will always be null, because mTarget is assigned a value in the Down event. Since mTarge is null, the ViewGroup's onTouchEvent event is executed. In this case, the ViewGroup can be treated directly as a View.

2. If we are in the onInterceptTouchEvent of a ViewGroup, all Touch events whose Action is Down return false, and the others return True. In this case, the Down event can be distributed normally. If the child Views all return false, then mTarget is still empty, no impact. If a sub-View returns true and mTarget is assigned a value, when Action_Move and Aciton_UP are distributed to the ViewGroup, a MotionEvent of Action_Delete will be distributed to mTarget, and the value of mTarget will be cleared at the same time, so that the next Action_Move (if the previous operation is not UP) will be handled by ViewGroup's onTouchEvent.

Situation 1 is used more often, while Situation 2 has not yet been used.

Summary from beginning to end:

1. There are only two protagonists in Touch event distribution: ViewGroup and View. ViewGroup contains three related events: onInterceptTouchEvent, dispatchTouchEvent, and onTouchEvent. View contains two related events: dispatchTouchEvent and onTouchEvent. Among them, ViewGroup inherits from View.

2. ViewGroup and View form a tree structure, and the root node is a ViwGroup contained within the Activity.

3. The touch event consists of Action_Down, Action_Move, and Aciton_UP. In a complete touch event, there is only one Down and Up, and there are several Moves, which can be 0.

4. When Acitivty receives the Touch event, it will traverse the sub-View to distribute the Down event. ViewGroup traversal can be viewed as recursive. The purpose of distribution is to find the View that actually handles this complete touch event. This View will return true in the onTouchuEvent result.

5. When a sub-View returns true, the distribution of the Down event will be stopped and the sub-View will be recorded in the ViewGroup. The subsequent Move and Up events will be handled directly by the sub-View. Since the sub-View is stored in the ViewGroup, in the multi-layer ViewGroup node structure, the upper-level ViewGroup saves the ViewGroup object where the View that actually handles the event is located: for example, in the structure of ViewGroup0-ViewGroup1-TextView, TextView returns true, which will be saved in ViewGroup1, and ViewGroup1 will also return true and be saved in ViewGroup0. When the Move and UP events come, they will first be passed from ViewGroup0 to ViewGroup1, and then from ViewGroup1 to TextView.

6. When all sub-Views in the ViewGroup do not capture the Down event, the onTouch event of the ViewGroup itself will be triggered. The way to trigger is to call the super.dispatchTouchEvent function, which is the dispatchTouchEvent method of the parent class View. When all sub-Views are not processed, the onTouchEvent method of Activity is triggered.

7.onInterceptTouchEvent has two functions: 1. Intercept the distribution of Down events. 2. Stop the delivery of Up and Move events to the target View, so that the ViewGroup where the target View is located captures the Up and Move events.
Supplement:

"Touch events are composed of Action_Down, Action_Move, and Aciton_UP. In a complete touch event, there is only one Down and Up, and there are several Moves, which can be 0.", here In addition, in fact, there may be 0 UP events.
The above is the entire content of this article. I hope it will be helpful for everyone to understand the Touch event distribution mechanism.

For more articles related to the 30-minute understanding of the Android Touch event distribution mechanism, please pay attention to the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Is the company's security software causing the application to fail to run? How to troubleshoot and solve it? Is the company's security software causing the application to fail to run? How to troubleshoot and solve it? Apr 19, 2025 pm 04:51 PM

Troubleshooting and solutions to the company's security software that causes some applications to not function properly. Many companies will deploy security software in order to ensure internal network security. ...

How to simplify field mapping issues in system docking using MapStruct? How to simplify field mapping issues in system docking using MapStruct? Apr 19, 2025 pm 06:21 PM

Field mapping processing in system docking often encounters a difficult problem when performing system docking: how to effectively map the interface fields of system A...

How to elegantly obtain entity class variable names to build database query conditions? How to elegantly obtain entity class variable names to build database query conditions? Apr 19, 2025 pm 11:42 PM

When using MyBatis-Plus or other ORM frameworks for database operations, it is often necessary to construct query conditions based on the attribute name of the entity class. If you manually every time...

How do I convert names to numbers to implement sorting and maintain consistency in groups? How do I convert names to numbers to implement sorting and maintain consistency in groups? Apr 19, 2025 pm 11:30 PM

Solutions to convert names to numbers to implement sorting In many application scenarios, users may need to sort in groups, especially in one...

How does IntelliJ IDEA identify the port number of a Spring Boot project without outputting a log? How does IntelliJ IDEA identify the port number of a Spring Boot project without outputting a log? Apr 19, 2025 pm 11:45 PM

Start Spring using IntelliJIDEAUltimate version...

How to safely convert Java objects to arrays? How to safely convert Java objects to arrays? Apr 19, 2025 pm 11:33 PM

Conversion of Java Objects and Arrays: In-depth discussion of the risks and correct methods of cast type conversion Many Java beginners will encounter the conversion of an object into an array...

How to elegantly get entity class variable name building query conditions when using TKMyBatis for database query? How to elegantly get entity class variable name building query conditions when using TKMyBatis for database query? Apr 19, 2025 pm 09:51 PM

When using TKMyBatis for database queries, how to gracefully get entity class variable names to build query conditions is a common problem. This article will pin...

E-commerce platform SKU and SPU database design: How to take into account both user-defined attributes and attributeless products? E-commerce platform SKU and SPU database design: How to take into account both user-defined attributes and attributeless products? Apr 19, 2025 pm 11:27 PM

Detailed explanation of the design of SKU and SPU tables on e-commerce platforms This article will discuss the database design issues of SKU and SPU in e-commerce platforms, especially how to deal with user-defined sales...

See all articles