Android Touch event Transfer Mechanism

Source: Internet
Author: User

Android Touch event Transfer Mechanism

 

 

In the previous article, I mainly explained the Touch event transfer process in the Android source code. Now I want to use a demo and an instance to learn about the Touch event handling process in Andorid.

In the Android system, the three functions closely related to Touch event distribution and processing are as follows:
(1) public boolean dispatchTouchEvent (MotionEvent ev)
(2) public boolean onInterceptTouchEvent (MotionEvent ev)
(3) public boolean onTouchEvent (MotionEvent event)


I have analyzed their source code in the previous article: method 1 mainly distributes Touch events, and method 2 mainly intercepts Touch events, method 3: process Touch events

These three methods mainly exist in ViewGroup, View, and Activity, as shown in the following figure:

 

 

 

ViewGroup

View

Activity

DispatchTouchEvent

Yes

Yes

Yes

OnInterceptTouchEvent

Yes

None

None

OnTouchEvent

Yes

Yes

Yes


 

Next we will use a demo to look at the execution process of these methods:
Custom class: MyLayoutFirst. java

 

public class MyLayoutFirst extends LinearLayout{  private static final String TAG = MyLayoutFirst;  public MyLayoutFirst(Context context, AttributeSet attrs)  {    super(context, attrs);  }    @Override  public boolean onInterceptTouchEvent(MotionEvent ev)  {    Log.w(yzy, MyLayoutFirst->onInterceptTouchEvent->+MyUtils.getActionName(ev));    return super.onInterceptTouchEvent(ev);  }    @Override  public boolean onTouchEvent(MotionEvent event)  {    Log.e(yzy, MyLayoutFirst->onTouchEvent->+MyUtils.getActionName(event));    return super.onTouchEvent(event);  }    @Override  public boolean dispatchTouchEvent(MotionEvent ev)  {    Log.i(yzy, MyLayoutFirst->dispatchTouchEvent->+MyUtils.getActionName(ev));    return super.dispatchTouchEvent(ev);  }  }

Customize a class; MyLayoutSecond. java

 

 

public class MyLayoutSecond extends LinearLayout{  private static final String TAG = MyLayoutSecond;  public MyLayoutSecond(Context context, AttributeSet attrs)  {    super(context, attrs);  }    @Override  public boolean onTouchEvent(MotionEvent event)  {    Log.e(yzy, MyLayoutSecond->MyLayoutSecond->+MyUtils.getActionName(event));    return super.onTouchEvent(event);  }    @Override  public boolean onInterceptTouchEvent(MotionEvent ev)  {    Log.w(yzy, MyLayoutSecond->onInterceptTouchEvent->+MyUtils.getActionName(ev));    return super.onInterceptTouchEvent(ev);  }    @Override  public boolean dispatchTouchEvent(MotionEvent ev)  {    Log.i(yzy, MyLayoutSecond->dispatchTouchEvent->+MyUtils.getActionName(ev));    return super.dispatchTouchEvent(ev);  } }

Add to main_layout.xml

 

 

     
          
               
       
  
 

Add the onTouchEvent method to MainActivity

 

 

public class MainActivity extends Activity{  @Override  protected void onCreate(Bundle savedInstanceState)  {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);  }  @Override  public boolean onCreateOptionsMenu(Menu menu)  {    // Inflate the menu; this adds items to the action bar if it is present.    getMenuInflater().inflate(R.menu.main, menu);    return true;  }    @Override  public boolean dispatchTouchEvent(MotionEvent ev)  {    Log.i(yzy, MainActivity->dispatchTouchEvent->+MyUtils.getActionName(ev));    return super.dispatchTouchEvent(ev);  }    @Override  public boolean onTouchEvent(MotionEvent event)  {    Log.e(yzy, MainActivity->onTouchEvent->+MyUtils.getActionName(event));    return super.onTouchEvent(event);  }}

The last tool class is used to convert the event id to a string.

 

 

public class MyUtils{  private static final String TAG = MyUtils;  public static String getActionName(MotionEvent event)  {    String name=;    switch(event.getAction())    {      case MotionEvent.ACTION_DOWN:        name=ACTION_DOWN;        break;      case MotionEvent.ACTION_MOVE:        name=ACTION_MOVE;        break;      case MotionEvent.ACTION_UP:        name=ACTION_UP;        break;    }    return name;  }}

Running Effect

 

 

The blue part is MyLayoutSecond. java, and the red part is MyLayoutFirst. java.
Now click the blue part: running result

It can be seen that the event is first captured by the Activity and then distributed to MyLayoutFirst. MyLayoutFirst calls its onInterceptTouchEvent to determine whether to intercept the event. Because the default return value is false, the event is not intercepted, in this way, the event is distributed to MyLayoutSecond, and MyLayoutSecond is also distributed through dispatchTouchEvent. Before the event is distributed, check whether it is intercepted. By default, no subview is provided because MyLayoutSecond does not exist, all the final events are handled by themselves and the onTouchEvent method of the method is called. Because this method returns false by default, the event is considered to have not been consumed and is passed to MyLayoutFirst, similarly, this event was not consumed and finally passed to Mainactivity. Later, we can see that ACTION_MOVE and ACTION_UP are not passed into MyLayoutFirst and MyLa. YoutSecond, because once an event is not processed, subsequent events will not be distributed. Therefore, ACTION_MOVE and ACTION_UP are directly processed by MainActivity.

Next, let's look at the second situation:

 

 

MainActivity

MyLayoutFirst

MyLayoutSecond

DispatchTouchEvent

Super. dispatchTouchEvent

Super. dispatchTouchEvent

Super. dispatchTouchEvent

OnInterceptTouchEvent

--

True

Super. onInterceptTouchEvent (ev)

OnTouchEvent

Super. onTouchEvent

Super. onTouchEvent

Super. onTouchEvent

The running result is as follows:

 

It can be seen that the event is not distributed to MyLayoutSecond after it is passed to MyLayoutFirst, and its onTouchEvent is directly called. Because the returned value is false, the event is not consumed and is finally passed to MainActivity,
In addition, subsequent events are not passed to MyLayoutFirst and MyLayoutSecond and are directly processed by MainActivity.

 

Case 3:

 

MainActivity

MyLayoutFirst

MyLayoutSecond

DispatchTouchEvent

Super. dispatchTouchEvent

Super. dispatchTouchEvent

Super. dispatchTouchEvent

OnInterceptTouchEvent

--

True

Super. onInterceptTouchEvent (ev)

OnTouchEvent

Super. onTouchEvent

True

Super. onTouchEvent

Running result:

 

Different from scenario 2, MyLayoutFirst's onTouchEvent returns true, that is, MyLayoutFirst consumes this event, so ACTION_DOWN is not passed to MainActivity, and ACTION_MOVE and ACTION_UP
All are passed to MyLayoutFirst

 

Fourth case:

 

MainActivity

MyLayoutFirst

MyLayoutSecond

DispatchTouchEvent

Super. dispatchTouchEvent

Super. dispatchTouchEvent

Super. dispatchTouchEvent

OnInterceptTouchEvent

--

Super. onInterceptTouchEvent (ev)

Super. onInterceptTouchEvent (ev)

OnTouchEvent

Super. onTouchEvent

Super. onTouchEven

True

Running result:

 

All events are consumed after being passed to MyLayoutSecond.

 

In fact, there are many other combinations. If you are interested, you can try to change the return values of each function and view the printed results. I will not list them here .....


Finally, I will provide a small demo to demonstrate how to solve the sliding conflict. The background is as follows:
A ViewPager contains two Framgent, and one Fragment contains a HorizontalListView. How to slide and conflict?
I will post the key code.

 

 

horizontal=(HorizontalListView)view.findViewById(R.id.hscroll);    horizontal.setOnTouchListener(new OnTouchListener()    {            @Override      public boolean onTouch(View arg0, MotionEvent event)      {        if(event.getAction()==MotionEvent.ACTION_DOWN)        {          parent.requestDisallowInterceptTouchEvent(true);        }else if(event.getAction()==MotionEvent.ACTION_UP)        {          parent.requestDisallowInterceptTouchEvent(false);        }        return false;      }    });

By adding this code, you can avoid slide conflicts. As for why, I will upload and download the two demo examples in my previous article "Android Touch event transfer mechanism details ".

 

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.