美文网首页
Android View手势与事件分发

Android View手势与事件分发

作者: 森屿暖茶 | 来源:发表于2021-04-23 00:18 被阅读0次

Android-触摸时间与手势

单点触摸OnTouchListener

1.手指触碰屏幕时,触发MotionEvent事件。

2.该事件被OnTouchListener监听,可在它的onTouch()方法中获得该MotionEvent对象。

OnTouchListener 的单点触摸情况下 OnTouchListener 的多点触摸情况下

总结:OnTouchListener一般用于单点的触摸监听需求,虽然也可以用它基本的多点触控功能,但是复杂的双击,长按等实现起来比较麻烦,而且Api也提供了供多点触摸需求直接使用GestureDetector.OnGestureListener接口。它能满足大部分下的多点触控需求。

多点触摸(手势)OnGestureListener

3.通过GestureDetector转发MotionEvent对象给OnGestureListener。

4.我们可以通过OnGestureListener获得该对象,然后获取相关信息,以及做相关处理。

对于自定义View,使用手势识别有两处陷阱可能会浪费你的不少时间。(源于其他大神)

1:View必须设置longClickable为true,否则手势识别无法正确工作,只会返回Down, Show, Long三种手势 

2:必须在View的onTouchListener中调用手势识别,而不能像Activity一样重载onTouchEvent,否则同样手势识别无法正确工作

View可以绑定的时间监听方法:

setOnClickListener - 当view被点击的时候回调

setOnDragListener -当view被拖动时回调

setOnFocusChangeListener - 当view改变焦点的时候回调

setOnGenericMotionListener- 任意的手势时回调

setOnHoverListener -在视图上悬停的时候调用

setOnKeyListener - 当view有焦点时候按硬件键时候回调

setOnLongClickListener - 长时间按压时回调

setOnTouchListener- 触摸view回调

其他特殊的View拥有自己的监听方法:如EditText,recycleView等

事件分发

事件传递的顺序:Activity -> ViewGroup -> View

事件处理函数

3者描述 3者(viewGroup本身没有onTouchEvent,但是它继承于view所以也可以使用 onTouchEvent)

事件分发流程

流程

①从activity的dispatchTouchEvent方法开始,

dispatchTouchEvent()若返回false调用onTouchEvent。

dispatchTouchEvent()若返回true,则表示事件不在分发,super,表示不拦截事件的分发,继续向下分发,事件分发传递给viewGourp。

②传递到ViewGourp后,从ViewGourp的dispatchEvent开始。

dispatchTouchEvent()若返回true,则表示事件不在分发,supter,表示不拦截事件的分发,继续向下分发。

dispatchTouchEvent()supter时调用ViewGourp的onInterceptTouchEvent方法决定是否要拦截次事件。

onInterceptTouchEven()若返回true,调用ViewGourp的onTouchEvent,表示事件被我拦截了。若返回false、supter,表示不拦截事件的分发,继续分发给下层view的dispatchEvent的事件。

③当底层view的dispatchEvent收到分发事件。

dispatchTouchEvent()若返回true,则表示事件不在分发。super,表示不拦截事件的分发,继续向下分发,事件分发结束,调用本层view的onTouchEvent。

返回false,不再调用本view的onTouchEvent,而是回调父ViewGourp的onTouchEvent。

④onTouchEvent只能且只会向上传递。

返回true,表示本view消费处理了此次点击事件,上层不会再收到onTouch时间。返回false,表示本view不消费处理,交给上层viewGourp处理,回调给上层viewGourp的onTouch

总结

dispatchTouchEvent():事件分发

若返回true,则表示事件不在分发,后续的onInterceptTouchEven()或者 onTouchEvent()均不会被调用。

若返回false,则表示事件不会向下分发,会交于上层onTouchEvent()方法处理。

若返回super,则表示事件会分发。

onInterceptTouchEven():事件拦截

仅存在于ViewGourp的方法,表示事件是否拦截。

若返回true,则事件拦截,事件会交于本层onTouchEvent()方法处理。

若返回supe、falser,则表示事件不拦截,事件会继续向下层分发。

onTouchEvent();事件处理(消费)

仅会本层处理或向上传递。

若返回true,本层onTouchEvent()方法处理了。

若返回false,本层onTouchEvent()方法不处理,会调用上层的onTouchEvent()方法处理。

PS:事件的分发大体可以看成一个U型结构,只是可能会在中间的某一个环节断掉。

了解原理过后我们处理需求和冲突就手到擒来了,常见的滑动冲突,就引申出外部拦截和内部拦截的处理方式。

外部拦截(是否拦截的业务逻辑在父viewGroup的onInterceptTouchEvent()方法中处理)

父ViewGroup,重写onInterceptTouchEvent方法,根据业务需要,判断哪些事件是父Viewgroup需要的,需要的话就对该事件进行拦截,然后交由onTouchEvent方法处理,若不需要,则不拦截,然后传递给子view或子viewGroup。

内部拦截

内部拦截(是否拦截的业务逻辑在子view的dispatchTouchEvent()方法中处理)

子view中拦截事件,父viewGroup默认是不拦截任何事件的,所以,当事件传递到子view时, 子view根据自己的实际情况来,如果该事件是需要子view来处理的,那么子view就自己消耗处理,如果该事件不需要由子view来处理,那么就调用getParent().requestDisallowInterceptTouchEvent()方法来通知父viewgroup来拦截

外部拦截

相关文章

网友评论

      本文标题:Android View手势与事件分发

      本文链接:https://www.haomeiwen.com/subject/frvzlltx.html