Android 触摸事件传递机制
1 触摸事件的类型
- ACTION_DOWN : 用户手指按下操作,一般标志着触摸事件的开始.
- ACTION_MOVE : 用户按下后移动手指.
- ACTION_UP : 用户手指离开屏幕.触摸事件的结束.
一次屏幕的触摸操作中,ACTION_UP 和 ACTION_DOWN 是必须有的.ACTION_MOVE视情况而定.
2. 事件传递的三个阶段
-
事件分发(dispatch) : 事件的分发对应着
dispatchTouchEvent
方法,在Android系统中所有的事件都是通过这个方法进行分发的.函数原型 :
// 事件分发方法 public boolean dispatchTouchEvent(MotionEvent ev);
- 返回值
true
或false
: 当前视图将事件消耗,不再继续分发给子视图. - 返回值
super.dispatchTouchEvent(ev)
: 继续分发事件.
- 返回值
-
事件拦截(Intercept) : 事件的拦截对应着
onInterceptTouchEvent
方法.这个方法
只有在ViewGroup及其子类中才存在,View和Activity中不存在.函数原型 :
// 事件拦截 public boolean onInterceptTouchEvent(MotionEvent ev);
- 返回值
true
: 拦截此事件,不再继续分发.同时交给自身的onTouchEvent
方法进行消费. - 返回值
false
或super.onInterceptTouchEvent
: 不拦截事件,继续传递给子视图.
- 返回值
-
事件消费(Consume) : 事件消费对应着
onTouchEvent
方法.函数原型 :
// 消费函数 public void onTouchEvent(MotionEvent ev);
- 返回值
true
: 当前视图可以处理当前事件,事件将不会向上传递给父视图. - 返回值
false
: 当前视图处理不了该事件,事件会被传递给父视图的onTouchEvent
方法进行处理.
- 返回值
3. Android拥有事件传递处理能力的类
-
Activity : 拥有
dispatchTouchEvent
和onTouchEvent
方法. -
ViewGroup :
dispatchTouchEvent
、onInterceptTouchEvent
和onTouchEvent
-
View : :
dispatchTouchEvent
、onTouchEvent
4. View 的事件传递机制
参考代码 : app , 下面对程序及结果进行分析.
-
不进行人为干预. 不设置listener情况.
-
dispatchTouchEvent
和onTouchEvent
返回父类的同名方法. -
onTouch
返回false
运行结果 :
MainActivity: dispatchTouchEvent : DOWN MyTextView: dispatchTouchEvent : DOWN MyTextView: onTouchEvent : DOWN MainActivity: onTouchEvent : DOWN MainActivity: dispatchTouchEvent : UP MainActivity: onTouchEvent : UP
从LOG中可以看出事件传递方式如下 :
-
dispatchTouchEvent
方法从外层向内层传递. -
onTouchEvent
从内层向外层传递. - 如果某一层处理了事,那么当前事件序列的其他事件不会向下传递.对于当前情况下由于MainActivity
处理ACTION_DOWN
事件 所以该事件序列中的ACTION_UP
事件也就到MainActivity就不
再下发给子视图了.
-
-
不进行人为干预,设置listener情况.
onTouch返回false 运行结果 :
MainActivity: dispatchTouchEvent : DOWN MyTextView: dispatchTouchEvent : DOWN MainActivity: onTouch : DOWN MyTextView: onTouchEvent : DOWN MainActivity: dispatchTouchEvent : UP MyTextView: dispatchTouchEvent : UP MainActivity: onTouch : UP MyTextView: onTouchEvent : UP MainActivity: MyTextView OnClick
onTouch返回true 运行结果 :
// onTouch 返回true : the listener consume the event MainActivity: dispatchTouchEvent : DOWN MyTextView: dispatchTouchEvent : DOWN MainActivity: onTouch : DOWN MainActivity: dispatchTouchEvent : UP MyTextView: dispatchTouchEvent : UP MainActivity: onTouch : UP
LOG 信息显示事件是 MyTextView 视图处理的.
- 事件处理的流程
- 如果设置了listener则首先调用 listener 的
onTouch
方法.- 返回值
true
: 表示listener处理该事件.onTouchEvent
和onClick
不会被调用. - 返回值
false
: 表示listener不处理该事件.onTouchEvent
和OnClick
不会被调用.
- 返回值
-
onTouchEvent
如果onTouch
方法返回true
-
onClick
如果onTouch
方法返回true
- 如果设置了listener则首先调用 listener 的
- 事件处理的流程
-
dispatchTouchEvent
返回false
或true
在两种情况下当前视图都会消耗该事件,该事件不会继续分发给子视图.
同时不会调用onTouchEvent
,onClick
等方法
MainActivity 运行结果 :MainActivity: dispatchTouchEvent : DOWN MainActivity: dispatchTouchEvent : UP
MyTextView 运行结果
MainActivity: dispatchTouchEvent : DOWN MyTextView: dispatchTouchEvent : DOWN MainActivity: dispatchTouchEvent : UP MyTextView: dispatchTouchEvent : UP
-
onTouchEvent
方法返回true
当前视图消耗该事件,该事件处理不会向上传递.
OnClick
方法不被调用MyTextView 运行结果
MainActivity: dispatchTouchEvent : DOWN MyTextView: dispatchTouchEvent : DOWN MainActivity: onTouch : DOWN MyTextView: onTouchEvent : DOWN MainActivity: dispatchTouchEvent : UP MyTextView: dispatchTouchEvent : UP MainActivity: onTouch : UP MyTextView: onTouchEvent : UP
-
onTouchEvent
方法返回false
当前视图不处理该事件,事件将会被传递给上层控件处理.并且
onClick
不会被调用.MyTextView 运行结果
MainActivity: dispatchTouchEvent : DOWN MyTextView: dispatchTouchEvent : DOWN MainActivity: onTouch : DOWN MyTextView: onTouchEvent : DOWN MainActivity: onTouchEvent : DOWN MainActivity: dispatchTouchEvent : UP MainActivity: onTouchEvent : UP
-
onTouchEvent
返回super.onTouchEvent(ev)
MyTextView 运行结果 :
MainActivity: dispatchTouchEvent : DOWN MyTextView: dispatchTouchEvent : DOWN MainActivity: onTouch : DOWN MyTextView: onTouchEvent : DOWN MainActivity: dispatchTouchEvent : UP MyTextView: dispatchTouchEvent : UP MainActivity: onTouch : UP MyTextView: onTouchEvent : UP MainActivity: MyTextView OnClick
5. ViewGroup 事件传递
-
onIntercepTouchEvent
返回false
或super.onIntercepTouchEvent
在这种情况下,事件会继续分发.
MyRelativeLayout 运行结果 :
MainActivity: dispatchTouchEvent : DOWN MyRelativeLayout: dispatchTouchEvent : DOWN MyRelativeLayout: onInterceptTouchEvent : DOWN MyTextView: dispatchTouchEvent : DOWN MainActivity: onTouch : DOWN MyTextView: onTouchEvent : DOWN MainActivity: dispatchTouchEvent : UP MyRelativeLayout: dispatchTouchEvent : UP MyRelativeLayout: onInterceptTouchEvent : UP MyTextView: dispatchTouchEvent : UP MainActivity: onTouch : UP MyTextView: onTouchEvent : UP MainActivity: MyTextView OnClick
-
onInterceptTouchEvent
返回true
在这种情况下,此视图会拦截事件,并交给自身的
onTouchEvent
处理.
MyRelativeLayout 运行结果 :// 事件最终是Activity处理的. MainActivity: dispatchTouchEvent : DOWN MyRelativeLayout: dispatchTouchEvent : DOWN MyRelativeLayout: onInterceptTouchEvent : DOWN MyRelativeLayout: onTouchEvent : DOWN MainActivity: onTouchEvent : DOWN MainActivity: dispatchTouchEvent : UP MainActivity: onTouchEvent : UP
网友评论