The murders caused by the Android touch event delivery mechanism

Source: Internet
Author: User
Tags diff gety xdiff

respect for the original:http://blog.csdn.net/yuanzeyao/article/details/38942135


About the Android Touch event delivery mechanism I have written two articles before, I think I understand the Touche incident is quite clear, but recently encountered a problem, let me once again on the Android Touche event to learn.

My article about the Android Touche event delivery mechanism is as follows:

http://blog.csdn.net/yuanzeyao/article/details/37961997

http://blog.csdn.net/yuanzeyao/article/details/38025165


I have come to the following conclusions in these two articles:

1, if a view is clickable, then this view of the ontouchevent is bound to return true, that is, any touch event will be consumed

2, if a view for the Action_down event is not consumed (Ontouchevent return false), then the subsequent action_move,action_up will not be accepted, that is, there is no opportunity to deal with these events, These events are handled in the parent view.

3, if a viewgroup wants to intercept an event (without passing the event to the child view), it only needs to overwrite ViewGroup's onintercepttouchevent ( Motionevent ev) method, let him return true, or call requestdisallowintercepttouchevent ( true );

4. The Touche event in Android is a activity->decorview->viewgroup->view that passes from the bottom up layer


Having understood the above question, let's begin to look at the problems I have encountered.

When using Slidemenu, in the activity in the only place a textview, you will find that Slidemenu can not slide, at that time through the top of the title to slide, because the slidemenu is not very familiar with the At that time thought is slidemenu of which attribute used wrong, and then has not solved the problem, until a netizen said set TextView clickable to true can solve the problem, I tried a bit, but also! Ha ha... , do you understand the reason for this? If you don't understand, keep looking down.


According to my previous understanding of the Touche event, if set clickable, then Touche event must be textview to consume, if the textview consumed, then slidemenu how to achieve sliding? To solve this problem, or to see the source of Slidemenu?


Let's first look at the Customviewabove and Touche methods in Slidemenu.

@Overridepublic boolean onintercepttouchevent (motionevent ev) {if (!menabled) return false;final int action = Ev.getaction () & motioneventcompat.action_mask;if (ACTION = = Motionevent.action_down && DEBUG) log.v (TAG, " Received Action_down "); if (action = = Motionevent.action_cancel | | ACTION = = motionevent.action_up| | (Action! = Motionevent.action_down && Misunabletodrag)) {EndDrag (); return false;} Switch (action) {case motionevent.action_move:try{final int activepointerid = mactivepointerid;if (Activepointerid = = invalid_pointer) break;final int pointerindex = This.getpointerindex (EV, activepointerid); final float x = Motioneventcompat.getx (EV, POINTERINDEX); final float dx = x-mlastmotionx;final float Xdiff = math.abs (dx); final float y = Motioneventcompat.gety (EV, POINTERINDEX), final float Ydiff = Math.Abs (Y-mlastmotiony), if (DEBUG) log.v (TAG, "Oninterc Epttouch moved to: ("+ x +", "+ y +"), diff: ("+ Xdiff +", "+ Ydiff +"), Mlastmotionx: "+ Mlastmotionx"; if (xdifF > Mtouchslop && xdiff > Ydiff && thisslideallowed (dx)) {if (DEBUG) log.v (TAG, "starting drag! From Onintercepttouch "); StartDrag (); Mlastmotionx = X;setscrollingcacheenabled (true);} else if (Ydiff > Mtouchslop) {Misunabletodrag = true;}} catch (IllegalArgumentException e) {e.printstacktrace ();} Break;case MotionEvent.ACTION_DOWN:mActivePointerId = Ev.getaction () & ((Build.VERSION.SDK_INT >= 8)? MotionEvent.ACTION_POINTER_INDEX_MASK:MotionEvent.ACTION_POINTER_INDEX_MASK); Mlastmotionx = Minitialmotionx = Motioneventcompat.getx (EV, mactivepointerid); mlastmotiony = motioneventcompat.gety (EV, Mactivepointerid); if ( thistouchallowed (EV)) {misbeingdragged = False;misunabletodrag = False;if (Ismenuopen () && Mviewbehind.menutouchinquickreturn (Mcontent, Mcuritem, Ev.getx () + mscrollx)) {Mquickreturn = true;}} else {Misunabletodrag = true;} Break;case MotionEventCompat.ACTION_POINTER_UP:onSecondaryPointerUp (EV); break;} if (!misbeingdragged) {if (Mvelocitytracker = = null) {Mvelocitytracker = Velocitytracker.obtain ();} Mvelocitytracker.addmovement (EV);} return Misbeingdragged | | Mquickreturn;}

Look at this method, there is a logic in this method is that when sliding to a certain distance, it will return true, that is, to intercept the sliding event, the first action_down will definitely not intercept.

And look at Ontoucheevent.java.

@Overridepublic boolean ontouchevent (motionevent ev) {if (!menabled) return false;//if (!misbeingdragged &&!) thistouchallowed (EV))//return false;if (!misbeingdragged &&!mquickreturn) return false;final int action = Ev.getaction (); if (Mvelocitytracker = = null) {Mvelocitytracker = Velocitytracker.obtain ();} Mvelocitytracker.addmovement (EV), switch (action & motioneventcompat.action_mask) {case Motionevent.action_down :/* * If being flinged and user touches, stop the fling. Isfinished * would be false if being flinged. */completescroll ();//Remember where the motion event Startedmlastmotionx = Minitialmotionx = Ev.getx (); Mactivepointerid = Motioneventcompat.getpointerid (EV, 0); Break;case MotionEvent.ACTION_MOVE:if (!misbeingdragged) {if ( Mactivepointerid = = invalid_pointer) break;final int pointerindex = Getpointerindex (EV, mactivepointerid); final float x = Motioneventcompat.getx (EV, POINTERINDEX); final float dx = x-mlastmotionx;final float Xdiff = math.abs (dx); final float y = motioneventcompat.gety (ev, POINTERINDEX), final float Ydiff = Math.Abs (Y-mlastmotiony), if (DEBUG) log.v (TAG, "Ontouc H moved to: ("+ x +", "+ y +"), diff: ("+ Xdiff +", "+ Ydiff +") \nmisbeingdragged: "+ misbeingdragged +", Mlastmoti OnX: "+ Mlastmotionx); if (Xdiff > Mtouchslop | | (Mquickreturn && xdiff > Mtouchslop/4)) && xdiff > Ydiff && thisslideallowed (dx)) {if (DEBUG) log.v (TAG, "starting drag! From OnTouch "); StartDrag (); Mlastmotionx = X;setscrollingcacheenabled (true);} else {if (DEBUG) log.v (TAG, "OnTouch returning false"); return false;}} if (misbeingdragged) {//Scroll to follow the motion eventfinal int activepointerindex = Getpointerindex (EV, Mactivepointe RID); if (Mactivepointerid = = Invalid_pointer) {break;} Final float x = motioneventcompat.getx (EV, ACTIVEPOINTERINDEX); final float deltax = Mlastmotionx-x;mlastmotionx = X;floa T oldscrollx = Getscrollx (); float scrollx = oldscrollx + deltax;final float leftbound = Getleftbound (); FINAL Float rightbound = Getrightbound (); if (Scrollx < leftbound) {scrollx = Leftbound;} else if (Scrollx > Rightbound) {scrollx = Rightbound;} Don ' t lose the rounded componentmlastmotionx + = scrollx-(int) scrollx;scrollto ((int) scrollx, getscrolly ());p Agescrol LED ((int) scrollx);} Break;case MotionEvent.ACTION_UP:if (misbeingdragged) {final Velocitytracker velocitytracker = Mvelocitytracker; Velocitytracker.computecurrentvelocity (mmaximumvelocity), int initialvelocity = (int) Velocitytrackercompat.getxvelocity (Velocitytracker, Mactivepointerid); final int scrollx = GETSCROLLX ();//final int  Widthwithmargin = getwidth ()//final float pageoffset = (float) (scrollx% widthwithmargin)/widthwithmargin;//TODO test This. Should get better flinging behaviorfinal float pageoffset = (float) (SCROLLX-GETDESTSCROLLX (Mcuritem))/Getbehindwidth ( ), final int activepointerindex = Getpointerindex (EV, Mactivepointerid), if (mactivepointerid! = invalid_pointer) {final float x = MotioneventcompAt.getx (EV, ACTIVEPOINTERINDEX); final int totaldelta = (int) (x-minitialmotionx); int nextPage = Determinetargetpage (pag Eoffset, initialvelocity, Totaldelta); Setcurrentiteminternal (NextPage, True, true, initialvelocity);} else {setcurrentiteminternal (Mcuritem, True, true, initialvelocity);} Mactivepointerid = Invalid_pointer;enddrag ();} else if (Mquickreturn && mviewbehind.menutouchinquickreturn (mcontent, Mcuritem, Ev.getx () + mscrollx)) {//close The Menusetcurrentitem (1); EndDrag ();} Break;case MotionEvent.ACTION_CANCEL:if (misbeingdragged) {setcurrentiteminternal (Mcuritem, True, true); Mactivepointerid = Invalid_pointer;enddrag ();} Break;case Motioneventcompat.action_pointer_down: {final int index = MOTIONEVENTCOMPAT.GETACTIONINDEX (EV); final float x = motioneventcompat.getx (ev, index); Mlastmotionx = X;mactivepointerid = Motioneventcompat.getpointerid (EV, index); break;} Case MotionEventCompat.ACTION_POINTER_UP:onSecondaryPointerUp (EV); int pointerindex = This.getpointerindex (EV, MACtivepointerid); if (Mactivepointerid = = invalid_pointer) Break;mlastmotionx = Motioneventcompat.getx (EV, PointerIndex ); break;} return true;}

We focus on the Action_dwon event, for the Action_dwon event, Slidemenu is not intercepted, so passed to the TextView, because the default textview is not clickable, so is not to consume this event, If the TextView does not consume, then the incident is passed to Slidemenu, but we found that in Slidemenu also did not consume this event, remember our above conclusion 2, according to conclusion 2, we know that the subsequent events are not passed over, So it caused the slidemenu not to slide.


If we set the clickable, then the first action_down will be textview processed, so each subsequent event will be passed to TextView (if not intercepted, the actual result is intercepted, and is slidemenu processed, So the slidemenu slipped)


The murders caused by the Android touch event delivery mechanism

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.