View's event system 2 (event distribution)

1. Delivery rules

  1. MotionEventThe distribution is mainly completed by the following three methods:

    • public boolean dispatchTouchEvent(MotionEvent ev)

      For a root ViewGroup, this method is called first after the click time is generated. onInterceptTouchEventIt will decide whether to continue to distribute to the child View according to the return value of .

    • public boolean onInterceptTouchEvent(MotionEvent ev)

      dispatchTouchEventis called in and gets the return value .

      • If it returns true: ViewGroupthe current event will be intercepted, the event will ViewGroupbe handled, and it onTouchEventwill be called.
      • If it returns false: ViewGroupthe current time will be passed to the child View, and then the child View's dispatchTouchEventwill be called until the event is finally handled.
    • public boolean onTouchEvent(MotionEvent ev)

      When the time is distributed to the View, if the View is registered OnTouchListener, the method of the interface onTouchwill be called back, and the result of the callback will affect the subsequent processing:

      • If it onTouchreturns true : View's willonTouchEvent be called
      • If it onTouchreturns false : View's onTouchEventwill not be called
  2. When a click event is generated, its delivery process is as follows:

    Activity -> Window -> View

    • When View's onTouchEventreturns false, then its parent container's onTouchEventwill be called, and so on.
    • If Viewnone of them handle the event, a Activityhandler will eventually be delivered.
  3. Event delivery details:
    1. The same sequence of events starts when the finger touches the screen and ends when the finger leaves the screen.
      • A sequence of downevents begins with an upevent and ends with an event.
    2. Normally, an event can only be intercepted and consumed by one View.
    3. If a View intercepts an event, then the entire sequence of events can only be handled by it, and its 's onInterceptTouchEventwill not be called again.
    4. Once a View starts to process events, if it does not consume events, other events in the same event sequence will not be handed over to it for processing, and the events will be ACTION_DOWNhanded over to its parent element for processing. onTouchEventtransfer.
      • Once you decide to process an event, you must consume it or the parent element will re-engage in the process.
    5. If the View does not consume other events other than the down event, the click event will disappear and the parent element's onTouchEventwill not be called.
      • And the current View can continue to receive subsequent events, and eventually these disappearing click events will be passed to Activity management.
    6. ViewGroupEvents are not intercepted by default. ViewGroupThe onInterceptTouchEventdefault implementation of returns false.
    7. View doesn't implement onInterceptTouchEventmethods, its onTouchListenerwill be called as soon as a click event is passed to it.
    8. View's onTouchEventdefault returns true, that is, events are consumed by default. Unless the View is not clickable clickable == false, and cannot be long-pressed longClickable == false.
      • longClickableThe default is generally false.
      • Some Views clickabledefault to true, such as Buttoncontrols that require interaction.
      • Some Views clickabledefault to false, such as TextViewcontrols that do not require interaction.
      • View enableproperties that do not affect onTouchEventthe default return value.
    9. onClickThe premise that will happen: the current View is clickable, and it has received down and up events.
    10. The event delivery process is always passed to the parent element first, and then the parent element distributes it to the child View.
      • With requestDisallowInterceptTouchEventmethods, you can intervene in the event dispatch process of the parent element in the child element. Except ACTION_DOWNfor events.

2. Analysis of the distribution process

  1. Activity's distribution source for click events:

    //Activity.java
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }

    Events are first handed over to Window for distribution.

    • If all Views contained in the Window return false, the event will be handed back to the Activity for processing, and the Activity's onTouchEventwill be called.
    • If there is a View in the Window that handles the event, getWindow().superDispatchTouchEvent(ev)it will return true. At this time, the event has been handled and the distribution ends.
  2. WindowThe only class that implements the Handling Events
    interface is , which is implemented as follows:WindowPhoneWindowsuperDispatchTouchEvent

    public boolean superDispatchTouchEvent(MotionEvent event){
        return mDecor.superDispatchTouchEvent(event);
    }

    DecorView is Windowthe top-level View, and the View we setContentViewset is a child View of DecorView.

    From here, the event has been delivered to the top-level View.

  3. Top-level View's distribution of click events

    The distribution process has been introduced in the previous section, and we will summarize it here.
    In fact the distribution process is similar to traversing a View tree:

    1. Whenever it is distributed to a non-leaf node, it will call dispatchTouchEvent:
      • If the onInterceptTouchEventreturn of this node is true, indicating that the event is intercepted, the event is handled by this node.
      • If the node's onInterceptTouchEventreturn false, the event is dispatched to its child nodes.
    2. When a node receives an event distribution, it can choose whether to process it by itself, and onTouchEventthe returned values ​​are:

      • true: handle the event yourself, the distribution ends
      • false: do not process the event, the event will continue to be dispatched

      Additionally, each node onTouchEventhas a default return value:

      • non-leaf node or root, i.e. ViewGroup, then onTouchEventreturns false by default
      • Leaf nodes generally return true by default.
      • Some leaf nodes have inherent interactive properties, such as Button, which returns true by default.
    3. If all nodes do not handle the event, it will eventually be handed back to the Activity for processing.
  4. Handling of click events by Views other than ViewGroup

    1. Determine onTouchListenerwhether it is injected by the user. If injected, onTouchthe return value of the judgment:
      • onTouchReturns true: onTouchEventwill not be called.

    2, if it onTouchListeneris empty, or if it onTouchreturns false, onTouchEventit will be called.

    1. When onTouchEventcalled:
      • If either clickable or longClickable is true, the event will be consumed, then return true.
      • The method will be fired when the event is ACTION_UP performClick. If View is injected OnClickListener, its methods performClickwill be called internally .onClick

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325611560&siteId=291194637