Android Touch事件方法机制
来源:互联网 发布:银河证券股票交易软件 编辑:程序博客网 时间:2024/05/26 17:48
事件分发机制
Android的事件方法遵循一定的流程,即方法,拦截,消费.分别对应于以下方法:
dispatchTouchEvent: 分发事件onInterceptTouchEvent:拦截事件onTouchEvent:消费事件
能够响应这些方法的有ViewGroup,View,Activity.
Touch流程类别
Touch事件流程有两种一种是down,另外是move,up,这两种事件的分发机制有一定的区别.
Touch事件为什么有两种?我们可以看一下源码.
一.看ViewGroup对事件的分类处理
@Override public boolean dispatchTouchEvent(MotionEvent ev) { if (mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onTouchEvent(ev, 1); } .......... .......... //看这段代码, DOWN事件时,满足一定的条件才会走拦截 onInterceptTouchEvent // Check for interception. final boolean intercepted; if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) { final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0; if (!disallowIntercept) { intercepted = onInterceptTouchEvent(ev); ev.setAction(action); // restore action in case it was changed } else { intercepted = false; } } else { // There are no touch targets and this action is not an initial down // so this view group continues to intercept touches. intercepted = true; } .......................... //经过一系列的逻辑判断,走dispatchTransformedTouchEvent ..................... dispatchTransformedTouchEvent { ............ //最后走到孩子的dispatchTouchEvent handled = child.dispatchTouchEvent(transformedEvent); } }
上面 代码在mGroupFlags & FLAG_DISALLOW_INTERCEPT为false才会走拦截事件,如果为true就会走孩子的diapatchTouchEvent,那我们”ctrl+f”看mGroupFlags & FLAG_DISALLOW_INTERCEPT什么时候会被赋值:
只在一个地方找到
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { if (disallowIntercept == ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0)) { // We're already in this state, assume our ancestors are too return; } if (disallowIntercept) { mGroupFlags |= FLAG_DISALLOW_INTERCEPT; } else { mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT; } // Pass it up to our parent if (mParent != null) { mParent.requestDisallowInterceptTouchEvent(disallowIntercept); } }
上面的代码大概就是disallowIntercept为true就会修改标记值,请求父容器不要拦截,所以move事件会首先走到孩子的diapatchTiuchevent.
看Activity的处理
Activity实现了Window.Callback借口,复写dispatchTouchEvent,
/** * Called to process touch screen events. You can override this to * intercept all touch screen events before they are dispatched to the * window. Be sure to call this implementation for touch screen events * that should be handled normally. * * @param ev The touch screen event. * * @return boolean Return true if this event was consumed. */ public boolean dispatchTouchEvent(MotionEvent ev) { // 对down事件做单独的处理 if (ev.getAction() == MotionEvent.ACTION_DOWN) { onUserInteraction(); } if (getWindow().superDispatchTouchEvent(ev)) { return true; } return onTouchEvent(ev); }public boolean onTouchEvent(MotionEvent event) { if (mWindow.shouldCloseOnTouch(this, event)) { finish(); return true; } return false; }
从上面的代码看到,Activity的dispatchTouchEvent对down事件做了处理,通过调用onUserInteraction(),将down事件交给自己来处理.move和up交给onTouchEvent来消费(Activity不存在View的嵌套,就不会有拦截方法了).
上面的源码总算的Touch事件的分类说清楚了,下面我们就讲一讲这两类事件的流程.
move,up事件
1.dispatchTouchEvent: 分发事件 1.1--true不分发 触摸事件结束 1.2--false分发 ----2.onInterceptTouchEvent 2.2----true拦截 ----3.onTouchEvent:消费事件 3.1----true自己消费,走自己的触摸逻辑 3.2----false自己不消费,触摸结束 2.2----false不拦截,事件来到子View ----diapatchTv ----true不分发.走3 ----false分发,走自己的onInterceptTouchEvent..
总结:
move,up事件总是遵循上面的流程,对于嵌套的View,父View总是最先接收到触摸事件,子View最先响应事件(因为dispatchTouchEvent,onInterceptTouchEvent默认返回false).
down事件
对于down事件,流程与move,up有点不一样.google对down事件做了特别的处理,事件总是会先走到子View的diapatchTouchEvent.流程如下:
1.dispatchTouchEvent: 分发事件 if(满足一定的条件) { 走子View的dispatchTouchEvent... }else{ 正常的move,up... }
满足的条件即子View对父容器的要求,即通过调用requestDisallowInterceptTouchEvent,设置几个标记,让父容器走拦截还是将down事件传给子View.
总结:
对于down事件,子VIew可以通过requestDisallowInterceptTouchEvent来获取事件的处理.google通过提供这个接口,防止父容器把事件给拦截了,让子View在需要时不能处理这个事件.
滑动冲突
在多层嵌套的view当中(如ViewPager与ViewPager,ScroolView与ViewPager……),经常会出现滑动的冲突,主要对Touch事件的流程比较清楚.在什么时候让父容器响应,什么时候让子View处理,通过Touch流程可以一一处理.
对于滑动冲突情况,很多博客都有将,参照一下这篇博客.
- Android Touch事件方法机制
- Android Touch 事件机制
- Android Touch事件处理机制
- Android Touch事件分发机制
- Android Touch事件分发机制
- Android Touch事件传递机制
- Android Touch事件传递机制
- Android Touch事件传递机制
- Android Touch事件传递机制
- Android Touch事件传递机制
- Android Touch事件传递机制
- Android Touch事件传递机制
- Android Touch事件传递机制
- 掌握Android Touch事件机制
- android touch事件分发机制
- android Touch事件分发机制
- Android Touch事件传递机制
- Android Touch事件分发机制
- Uva11762 Race to 1 数学期望
- 第1章 Android的构成基石-四大组件
- Android studio中logcat时间与真实时间不一致的问题
- Enterprise Architect 的安装与使用
- read()函数流程(USB读取文件)
- Android Touch事件方法机制
- eclipse使用hibernate tools插件使用、以及生成POJO
- 算法高效算法
- JDBC概述
- Codeforces Round #368 (Div. 2) D. Persistent Bookcase(离线)
- CheckIO Striped Words
- Apache HttpClient4.5(二)
- hdu 1004
- 51nod oj 1281 山峰和旗子【打表+枚举判断】