WEB开发网
开发学院手机开发Android 开发 android中ScrollView嵌套上下滑动开关球挺在中间问... 阅读

android中ScrollView嵌套上下滑动开关球挺在中间问题

 2013-09-04 20:06:37 来源:WEB开发网   
核心提示: 实现了一个仿iphone的slipbutton功能,并嵌套了一层ScrollView出现此问题,android中ScrollView嵌套上下滑动开关球挺在中间问题,初步分析和ScrollView的上下滑动产生了冲突,试过各种屏蔽,结论:ACTION_CANCEL事件是收到前驱事件后,后续事件被父控件拦截的情况下产生,

 实现了一个仿iphone的slipbutton功能,并嵌套了一层ScrollView出现此问题,初步分析和ScrollView的上下滑动产生了冲突,试过各种屏蔽,如判断如果左右滑动小于上下滑动则此时屏蔽掉ScrollView的上下滑动事件,还有就是在SlipButton中的MotionEvent.ACTION_MOVE中判断手指滑动是否超出SlipButton范围,发现坐标不对,始终没办法得到判断,也发现只要滑动到外部根本就没办法触发MotionEvent.ACTION_UP事件,很是奇怪。后来查阅官方文档,发现了这个事件:ACTION_CANCEL,国外解释是:
You receive this when a parent takes possession of the motion, for example when the user has dragged enough across a list view or scroll view that it will start scrolling instead of letting you press the buttons inside of it.
其实简单说就是:当前手势被释放,你将不会接收到其他的事件,应该向ACTION_UP一样对待它。
这就是重点了!在设计设置页面的滑动开关时,如果不监听ACTION_CANCEL,在滑动到中间时,如果你手指上下移动,就是移动到开关控件之外,则此时会触发ACTION_CANCEL,而不是ACTION_UP,造成开关的按钮停顿在中间位置。意思就是,当用户保持按下操作,并从你的控件转移到外层控件时,会触发ACTION_CANCEL,建议在此方法中进行处理。

什么情况会触发这个事件呢?
当当前控件(子控件,儿子)收到前驱事件(ACTION_MOVE或者ACTION_MOVE)后,它的父控件(老爸)突然插手,截断事件的传递,这时,当前控件就会收到ACTION_CANCEL,收到此事件后,不管子控件此时返回true或者false,都认为这一个动作已完成,不会再回传到父控件的OnTouchEvent中处理,同时后续事件,会通过dispatchEvent方法直接传送到父控件这里来处理。这和之前的结论有点相悖,之前说过如果子控件的OnTouchEvent返回false,表明事件未被处理,是回传到父控件去处理的,这里纠正一下,只有ACTION_DOWN事件才可以被回传,ACTION_MOVE和ACTION_UP事件会跟随ACTION_DOWN事件,即ACTION_DOWN是哪个控件处理的,后续事件都传递到这里,不会上抛到父控件,ACTION_CANCEL也不能回传。还有一点,触摸区域的范围问题,如果触摸区域在子控件内,同时父控件没有截断事件传递,刚不管子控件是否拦截此事件,都会传递到子控件的OnTouchEvent中处理,可以看成一种责任吧,因为我点的就是你,你父亲没有拦截,说明他不想处理,那到你这里了,不管你拦不拦截,都得你来处理。
结论:ACTION_CANCEL事件是收到前驱事件后,后续事件被父控件拦截的情况下产生,onTouchEvent的事件回传到父控件只会发生在ACTION_DOWN事件中。

Tags:android ScrollView 嵌套

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接