Android Kernel Analysis Reading Notes Chapter 1 view working principle [Touch message distribution]

Source: Internet
Author: User
Tags gety

Compared with a key message, a touch message is also received by the viewrootimpl. windowinputeventreceiver instance. Different methods are executed after the message type is determined.
The deliverpointerevent (.) method has the following differences:

  1. The inputmanagerservice of the message retrieval module sends a touch message directly to the application without any internal preprocessing of WMS. In the latest version, the message is only executed when the screen is disabled.
    Interceptmotionbeforequeueingwhenscreenoff (.);
  2. When processing a touch message, you need to calculate the view/viewgroup to which the message should be distributed based on the coordinate of the touch point, but the calculation process does not exist in the processing of the key message;
  3. There is no "System touch" like "system buttons", and applications can fully control the touch behavior;
  4. The sub-view takes precedence over the parent view for message processing, which is totally different from the processing mechanism of key messages;

Relationship between screen coordinates, View coordinates, and layout coordinates

  1. Screen coordinates: The coordinates are (0, 0) at the top left of the screen. The maximum value of x/y indicates the width and height of the physical screen resolution;
    The screen coordinate value is obtained by touching motionevent. getx/Gety in the message;
  2. View coordinates: View coordinates are coordinate systems completely determined by the width and height of the View content. Theoretically, they have no boundaries and are not limited by the size of the physical screen;
    For example, if the text of the first row is limited to 1000 Px in width and the height of each row is 5 PX, the x/y coordinate value is );
  3. Layout coordinates: The relative screen coordinates of the Child view relative to the parent view. The upper left corner of the parent view is (0, 0), regardless of where the parent view is on the screen, the maximum coordinate value of x/y is the width/height of the parent view. For a child view, if the content is too large, the area size that exceeds the size allocated by the parent view cannot be displayed in some content, the scroll bar appears. View coordinates = layout coordinates + mscrollx/mscrolly;
    In the view system, getx/Gety/gettop/getbottom/getleft/getright indicates the layout coordinates;
    The screen coordinates of the sub-view = the layout coordinates of the sub-view + the screen coordinates of the parent view. The View coordinates and layout coordinates can be converted. For details, see the example. Note: the blank area is not in size, just for a clearer demonstration;

Overall touch message distribution process

The following describes how viewrootimpl executes the deliverpointerevent (.) method when receiving a specific message:

  1. Physical pixel to logical pixel conversion is required only when the physical screen pixel is inconsistent with the screen pixel identified in the operating system;
  2. If it is a down event, call the ensuretouchmode (true) method to set it to the touch mode, which will cause changes to the view status. For details, refer to the subsequent instructions;
  3. Convert the screen coordinates to view coordinates, because you need to determine which view to process the message based on the coordinates of the touch point;
  4. Call mview. dispatchtouchevent () to distribute the message to the root view. The mview instance here is phonewindow. decorview;
    1. Determine whether a window exists. the callback object is actually an activity instance. If it does not exist, call decorview directly. super. dispatchtouchevent (EV), which is actually executed by viewgroup. dispatchtouchevent (.), note: viewgroup completely reloads this method and does not call the super method;

      1. Execute onintercepttouchevent (.); intercept the current event and return whether the current viewgroup needs to process the message by itself to control the event transmission direction. developers can call requestdisallowintercepttouchevent (.) sets whether message interception is allowed;
      2. If not, traverse all sub-views and use istransformedtouchpointinview (...) Determine whether the current touch point is within the subview, locate the subview that can process the message, and then execute dispatchtransformedtouchevent (...), Call
        Child. dispatchtouchevent (.); for child views, if it is a viewgroup instance, the previous logic is looping; if not, view. dispatchtouchevent (.) is executed (.);

        1. First, determine whether the current view has set the view. ontouchlistener interface listener. If yes, execute the listener instance
          Ontouch (.) method;
          Note: This listener is only valid for non-viewgroup subclasses, because viewgroup completely reloads the dispatchtouchevent method and has no chance to call the listener method;
        2. If no, the ontouchevent (.) is executed directly (.) method; in the Base Class View. ontouchevent (.) the method processes the three click events, namely, tap, click, and longclick.
          Onclicklistener/onlongclicklistener interface callback. Developers only need to implement the corresponding listener interface. The corresponding event processing model is as follows:

          Note: The tap does not listen to the listener interface separately, and it does not change the view status, but it will cause the view to get the focus, therefore, some of our selector's ui effects on the pressed status settings do not work for the TAP; because the time interval between the tap is only 180 ms, so to experience the specific UI effect, it takes a quick touch;
      3. If you need to process it yourself, directly execute dispatchtransformedtouchevent (...);
    2. If an activity callback instance exists, execute the activity. dispatchtouchevent () method;
      1. If the message is down, onuserinteraction () is called. You can call the onuserinteraction () method to specify what can be done before the message is processed. This method is applicable to buttons and touch messages. if the message is overloaded, it will take effect for both;
      2. Run phonewindow. superdispatchtouchevent (); it is actually transferred to decorview. super. dispatchtouchevent (.) processing, which is consistent with the absence of activity callback instances, that is, in any case, the view first processes the message and then the activity processes the message;
      3. If the view system does not process the message, activity. ontouchevent (.) is called. developers can reload this method to implement their own processing logic;

Detailed logical relationship between dispatchtouchevent/onintercepttouchevent/ontouchevent in view/viewgroup

  1. In a multi-layer nested view system, touch events are transmitted from the top layer to the bottom layer. In the viewgroup, dispatchtouchevent (.) recursive call is performed. The child view takes precedence over the parent view for message processing. Generally, the whole shows a U-type recursion, as shown in. layoutview1 includes the child view layoutview2 and layoutview2 includes the child view textview;
  2. Dispatchtouchevent is the source of event processing. The specific processing logic of View/viewgroup is completely different. For details, see the specific content above;
    Ontouchevent is an open callback Method for developers to process specific messages. Of course, in the default implementation, the system further extracts many listener callback interfaces for developers to use;
    Onintercepttouchevent is unique to viewgroup and is called in dispatchtouchevent. This gives viewgroup the opportunity to decide whether to process the touch message or pass it to the subview for processing;
  3. All touch events start with a down event, and will be moved multiple times in the middle, and finally ended with an up event;
  4. If viewgroup. onintercepttouchevent (): if false is returned for processing the down event, the viewgroup does not intercept the event and submits it to the subview for processing, events such as up will be passed to the viewgroup first, and then to the subview for processing.
    Note: If the sub-view does not process the down event, then the current viewgroup. ontouchevent processes the event, and the subsequent move/Up event will skip the viewgroup. onintercepttouchevent () and directly execute viewgroup. ontouchevent;
  5. If viewgroup. onintercepttouchevent () returns true for down event processing, subsequent move/up events will not be passed to onintercepttouchevent (), but will be passed directly to the ontouchevent () of the viewgroup for processing;
    Note: In this case, the child view will not receive any event because it is intercepted by the parent view.
  6. If the ontouchevent () of the Child view returns false, the current event will be passed to the ontouchevent () of the parent view for processing, and subsequent events will not be passed to the Child view.
    Note: this refers to the processing of down events. If it is another event, the event is not transmitted to the parent view even if the ontouchevent () of the subview returns false;
  7. If the ontouchevent () of the Child view returns true, the ontouchevent () of the parent view of the current event will not be triggered, and subsequent events of the Child view will continue to be triggered by the ontouchevent () of the Child view () if the current sub-view is still viewgroup, The onintercepttouchevent () will also be skipped and will not be executed.
  8. If no view. ontouchevent () returns true for the down event, the subsequent move and up events will be automatically discarded and will not be passed;
  9. If viewgroup. onintercepttouchevent () returns false to the down event, but returns true to the next move event. In this case, the system will send a cancel event to the Child view and the viewgroup of the current move event. ontouchevent () will not be executed, that is, the current move event is discarded, but the next new move/up message will directly enter the viewgroup. ontouchevent () execution;

Next, we will provide some case descriptions based on the above descriptions. For simple information, see http://blog.csdn.net/ddna/article/details/5473293;

Note: At present, most of the descriptions of touch event transfer on the network are not accurate enough. You can consider the following cases with your own consideration;

Because the touch message is an event series, including one down event, multiple move events, and one up event, the execution of onintercepttouchevent/ontouchevent is involved in each event, each execution can return true/false as needed, which leads to many combinations, but the principle is based on the above mentioned. Let's take a look at the following examples:

  1. The execution conditions are as follows:
    Layoutview1.onintercept always returns false;
    Layoutview2.onintercept always returns true;
    Layoutview1.ontouchevent always returns true;
    Layoutview2.ontouchevent always returns false;
    Mytextview. ontouchevent always returns true;
    The execution result is as follows:
    06-25 16:32:41. 779: D/layoutview1 (25253): onintercepttouchevent action: ACTION_DOWN06-25 16:32:41. 779: D/layoutview2 (25253): onintercepttouchevent action: action_down
    06-25 16:32:41. 784: D/layoutview2 (25253): ontouchevent action: action_down
    06-25 16:32:41. 784: D/layoutview1 (25253): ontouchevent action: action_down
    06-25 16:32:41. 789: D/layoutview1 (25253): ontouchevent action: action_move
    06-25 16:32:41. 804: D/layoutview1 (25253): ontouchevent action: action_move
    06-25 16:32:41. 974: D/layoutview1 (25253): ontouchevent action: action_move
    06-25 16:32:41. 979: D/layoutview1 (25253): ontouchevent action: action_up
    Explanation:
    For down events, layoutview1.onintercept is executed but not blocked, and layoutview2.onintercept is executed and intercepted. The event can be transferred to layoutview2.ontouchevent for processing. However, the event is handled by layoutview1.ontouchevent in the parent view and returns;
    For subsequent move/up events, layoutview1.ontouchevent is used directly, and the onintercept of layoutview1/2 is skipped;
  2. The execution conditions are as follows:
    Layoutview1.onintercept always returns false;
    Layoutview2.onintercept: Return false for the down event, but true for the move event;
    Layoutview1.ontouchevent always returns true;
    Layoutview2.ontouchevent always returns false;
    Mytextview. ontouchevent always returns false;
    The execution result is as follows:
    06-25 17:04:26. 764: D/layoutview1 (21298): onintercepttouchevent action: ACTION_DOWN06-25 17:04:26. 764: D/layoutview2 (21298): onintercepttouchevent action: action_down
    06-25 17:04:26. 764: D/mytextview (21298): ontouchevent action: action_down
    06-25 17:04:26. 764: D/layoutview2 (21298): ontouchevent action: action_down
    06-25 17:04:26. 764: D/layoutview1 (21298): ontouchevent action: action_down
    06-25 17:04:26. 804: D/layoutview1 (21298): ontouchevent action: action_move
    06-25 17:04:26. 819: D/layoutview1 (21298): ontouchevent action: action_move
    06-25 17:04:27. 059: D/layoutview1 (21298): ontouchevent action: action_move
    06-25 17:04:27. 064: D/layoutview1 (21298): ontouchevent action: action_up
    Explanation:
    For the down event, layoutview1.onintercept is executed but not intercepted, and layoutview2.onintercept is not intercepted and submitted to mytextview. ontouchevent processing, but because false is returned, the event is handed over to the parent view layoutview2.ontouchevent for execution, but unfortunately false is also returned. The layoutview1.ontouchevent is handed over for execution, and true is returned if messages are consumed successfully;
    For subsequent move/up events, layoutview1.ontouchevent is used directly, and the onintercept of layoutview1/2 is skipped;
  3. The execution conditions are as follows:
    Layoutview1.onintercept always returns false;
    Layoutview2.onintercept: Return false for the down event, but true for the move event;
    Layoutview1.ontouchevent always returns true;
    Layoutview2.ontouchevent always returns true;
    Mytextview. ontouchevent always returns true;
    The execution result is as follows:
    06-25 15:56:09. 219: D/layoutview1 (28368): onintercepttouchevent action: ACTION_DOWN06-25 15:56:09. 219: D/layoutview2 (28368): onintercepttouchevent action: action_down
    06-25 15:56:09. 219: D/mytextview (28368): ontouchevent action: action_down
    06-25 15:56:09. 254: D/layoutview1 (28368): onintercepttouchevent action: action_move
    06-25 15:56:09. 254: D/layoutview2 (28368): onintercepttouchevent action: action_move
    06-25 15:56:09. 254: D/mytextview (28368): ontouchevent action: action_cancel
    06-25 15:56:09. 274: D/layoutview1 (28368): onintercepttouchevent action: action_move
    06-25 15:56:09. 274: D/layoutview2 (28368): ontouchevent action: action_move
    06-25 15:56:09. 389: D/layoutview1 (28368): onintercepttouchevent action: action_move
    06-25 15:56:09. 389: D/layoutview2 (28368): ontouchevent action: action_move
    06-25 15:56:09. 389: D/layoutview1 (28368): onintercepttouchevent action: action_up
    06-25 15:56:09. 389: D/layoutview2 (28368): ontouchevent action: action_up
    Explanation:
    Layoutview1/2 does not intercept down events and is directly handled by mytextview;
    For the first move event, layoutview1 executes the onintercepttouchevent method but does not intercept it. layoutview2 executes the onintercepttouchevent method and blocks it. The move event is not directly handled by layoutview2.ontouchevent, instead, a cancel event is sent to mytextview and mytextview is executed. ontouchevent method;
    For subsequent move/up events, layoutview1 executes the onintercepttouchevent method and does not intercept it. Then, it directly enters layoutview2.ontouchevent for processing, and the layoutview2.onintercepttouchevent method will not be executed until the event ends;
  4. The execution conditions are as follows:
    Layoutview1.onintercept always returns false;
    Layoutview2.onintercept: Return false for the down event, but true for the move event;
    Layoutview1.ontouchevent always returns true;
    Layoutview2.ontouchevent always returns false; true is returned in the previous test;
    Mytextview. ontouchevent always returns true;
    The execution result is as follows:
    06-25 17:18:48. 914: D/layoutview1 (1819): onintercepttouchevent action: ACTION_DOWN06-25 17:18:48. 914: D/layoutview2 (1819): onintercepttouchevent action: action_down
    06-25 17:18:48. 914: D/mytextview (1819): ontouchevent action: action_down
    06-25 17:18:48. 954: D/layoutview1 (1819): onintercepttouchevent action: action_move
    06-25 17:18:48. 954: D/layoutview2 (1819): onintercepttouchevent action: action_move
    06-25 17:18:48. 954: D/mytextview (1819): ontouchevent action: action_cancel
    06-25 17:18:48. 964: D/layoutview1 (1819): onintercepttouchevent action: action_move
    06-25 17:18:48. 964: D/layoutview2 (1819): ontouchevent action: action_move
    06-25 17:18:49. 139: D/layoutview1 (1819): onintercepttouchevent action: action_move
    06-25 17:18:49. 139: D/layoutview2 (1819): ontouchevent action: action_move
    06-25 17:18:49. 139: D/layoutview1 (1819): onintercepttouchevent action: action_up
    06-25 17:18:49. 139: D/layoutview2 (1819): ontouchevent action: action_up
    Explanation:
    Layoutview1/2 does not intercept down events and is directly handled by mytextview;
    For the first move event, layoutview1 executes the onintercepttouchevent method but does not intercept it. layoutview2 executes the onintercepttouchevent method and blocks it. The move event is not directly handled by layoutview2.ontouchevent, instead, a cancel event is sent to mytextview and mytextview is executed. ontouchevent method;
    For subsequent move/up events, layoutview1 executes the onintercepttouchevent method and does not intercept it. Then, it directly enters layoutview2.ontouchevent for processing, and the layoutview2.onintercepttouchevent method will not be executed until the event ends;
    The execution result is exactly the same as that in the previous case. Why is the message returned by layoutview2.ontouchevent false but not sent to the parent view to execute layoutview1.ontouchevent? The reason is that the event is no longer a down event. The ontouchevent will be passed to the parent view only in the initial down event of the touch;
  5. The execution conditions are as follows:
    Layoutview1.onintercept always returns false;
    Layoutview2.onintercept always returns false;
    Layoutview1.ontouchevent always returns true;
    Layoutview2.ontouchevent always returns false;
    Mytextview. ontouchevent returns true for the down/Up event, but false for the move event;
    The execution result is as follows:
    06-25 18:05:21. 029: D/layoutview1 (9095): onintercepttouchevent action: ACTION_DOWN06-25 18:05:21. 029: D/layoutview2 (9095): onintercepttouchevent action: action_down
    06-25 18:05:21. 029: D/mytextview (9095): ontouchevent action: action_down
    06-25 18:05:21. 039: D/layoutview1 (9095): onintercepttouchevent action: action_move
    06-25 18:05:21. 039: D/layoutview2 (9095): onintercepttouchevent action: action_move
    06-25 18:05:21. 039: D/mytextview (9095): ontouchevent action: action_move
    06-25 18:05:21. 224: D/layoutview1 (9095): onintercepttouchevent action: action_move
    06-25 18:05:21. 224: D/layoutview2 (9095): onintercepttouchevent action: action_move
    06-25 18:05:21. 224: D/mytextview (9095): ontouchevent action: action_move
    06-25 18:05:21. 239: D/layoutview1 (9095): onintercepttouchevent action: action_up
    06-25 18:05:21. 239: D/layoutview2 (9095): onintercepttouchevent action: action_up
    06-25 18:05:21. 239: D/mytextview (9095): ontouchevent action: action_up
    Explanation:
    For down/move/up events, layoutview1/2 executes the onintercepttouchevent method but does not intercept it. ontouchevent processing; even if false is returned for down event processing, the move event is not handled by the parent view layoutview2.ontouchevent;
    This instance is the same as the above instance. It is only for the purpose of illustration: ontouchevent will be passed to the parent view only in the initial down event of the touch;

If the above content is reproduced, please indicate the source, welcome to visit the column http://blog.csdn.net/sfdev of laotang

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.