前言
但用户在程序中实现各种操作时,应用程序就应该针对用户的不同操作提供不同的响应事件。Android提供了两套事件处理机制。
基于监听的事件处理
基于回调的事件处理
基于监听的事件处理
基于监听的时间处理有如下规则
事件源:如程序中的bt按钮,应用程序中任何组件都可作为事件源
事件监听器:程序中的MyClickListener类,监听器类必须由程序员负责实现
注册监听器:只要调用事件源的setXXXListener(XXXListener)方法即可
基于回调的事件处理
为了实现回调机制的事件处理,Android为View控件都提供了一些事件处理的回调方法,如以下的方法:
boolean onKeyDown(int keyCode,KenyEvent enent):当用户在该组件上按下某个键时触发的方法。
boolean onKeyLongPress(int keyCode,KeyEvent event):当用户在该组件上长按某个按键时触发的方法。
boolean onKeyShortcut(int keyCode,KeyEvent event):当一个键盘快捷键事件触发时 触发的方法。
boolean onKeyUp(int keyCode,KeyEvent event):当用户在该组件上松开某个按键时触发的方法。
boolean onTouchEvent(MotionEvent event):当用户子在该组件上触发触摸屏事件时 触发的方法。
boolean onTrackballEvent(MotionEvent event):当用户在该组件上触发轨迹球屏事件时触发该方法。
易于发现,在每个触发事件的回调方法都有一个MotionEvent类,现在就我目前的理解来解释一下这个类
MotionEvent
这是Android为触摸事件封装的一个类,里面记录了用户触摸事件(触摸点坐标,轨迹等)的具体信息,下面是MotionEvent的常用姿势
event.getAction() or event.getAction() & MotionEvent.ACTION_MASK // 获取触控动作比如 ACTION_DOWN,
event.getPointerCount() //获取触控点的数量,比如2则可能是两个手指同时按压屏幕
event.getPoninerId(int index)//对于每个触控的点的细节,我们可以通过一个循环执行getPointerId方法获取索引
event.getX(int index)//获取第index个触控点的x位置
event.getY(int index)//获取第index个触控点的y位置
event.getPressure(int index)// LCD可以感应出用户的手指压力,当然具体的级别由驱动和物理硬件决定的
event.getDownTime()//按下开始时间
event.getEventTime()//事件结束时间
event.getEventTime() - event.getDownTime()//总共按下时花费时间
了解完MotionEvent后,我们捋一捋事件的分发流程。我们知道View结构是树形结构,其中有父ViewGroup和子View,那么事件应该由哪个来处理,这就引出了 事件拦截
事件拦截
事件拦截这里主要要梳理清楚父ViewGroup和子View之间的事件传递过程。
首先需要清楚,在父ViewGroup中涉及事件处理的三个方法
方法 | 解释 | ViewGroup | View |
---|---|---|---|
boolean dispatchTouchEvent(MotionEvent ev); | 事件分发 | yes | yes |
boolean onIntercapTouchEvent(MotionEvent ev); | 事件拦截 | yes | no |
boolean onTouchEvent(MotionEvent ev); | 事件处理 | yes | yes |
可以看出,父ViewGroup比子View多了一个onInterceptTouchEvent(MotionEvent ev)拦截事件。
而整个事件传递的流程如下
dispatchTouchEvent
如果 return true,事件会分发给当前 View 并由 dispatchTouchEvent 方法进行消费,同时事件会停止向下传递
如果 return false,事件会继续向下传递
该方法虽然是事件分发的第一步,但一般情况下,我们不太会去改写这个方法
onIntercapTouchEvent
如果 onInterceptTouchEvent 返回 true,则表示将事件进行拦截,并将拦截到的事件交由当前 View 的 onTouchEvent 进行处理;
如果 onInterceptTouchEvent 返回 false,则表示将事件放行,当前 View 上的事件会被传递到子 View 上,再由子 View 的 dispatchTouchEvent 来开始这个事件的分发;
资料
android MotionEvent的相关的类的介绍
Android MotionEvent详解
android view、viewgroup 事件响应拦截处理机制