android中的事件传递机制
android中的事件传递
当手指触摸屏幕时,会触发一个touch事件,这个touch事件在android中是怎么传递的呢,下面就让我们来看一看
(1)当一个touch事件来的时候,首先会传递给最顶层的view,有顶层的view,一级一级向下分发,知道找到点击的view,将这个消息传递给他
事件分发时会调用dispatchTouchEvent(MotionEvent ev)这个方法.
(2)顶层的view也可以选择不向下分发此事件,而是自己把这个事件给消耗了(这时会调用onInterceptTouchEvent(MotionEvent ev)方法,来消耗掉此事件),这样子view就不会收到这个touch事件,
这时这个touch事件会交给顶层的onTouchEvent(MotionEvent event)执行
(3)当事件传递给最终的子view时,子view返回true表示此事件已经处理完毕,不需要交给父view在进行处理,
当子view返回false时,表示子view不处理这个事件,事件将会向上传递,交给父view进行处理,当父view全部返回false时,这个事件谁也不会处理
这时,这个事件也只会传递给子view一次,下次不会在传递给子view了
比如,写一个类继承自ViewGroup
public class MyScrollPager extends ViewGroup{
GestureDetector gestureDetector;//手势识别器
private float firstX = 0;//初始x位置
private float firstY = 0;//初始y位置
//设置滑动监听
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
gestureDetector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
/**
* 事件的中断,true—>本层中断,不向下传递
*/
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean bool = false;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
//当事件在这层中断掉以后,紧接着执行ontouchevent方法,
//在ontouchevent方法中将收不到action_keydown消息,
//因此手势识别器收不到key_down消息,因此会出现跳动现象
gestureDetector.onTouchEvent(ev);
firstX = ev.getX();
firstY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
float disx = Math.abs(ev.getX() - firstX);
float disy = Math.abs(ev.getY()- firstY);
//如果水平滑动的距离大于竖直滑动的距离
//并且x轴防止抖动
if(disx > disy && disx > 10){
bool = true;
}else{
bool = false;
}
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
return bool;
}
}
在这个方法中重写了onInterceptTouchEvent,onTouchEvent方法,
这两个方法的意思是当手指左右滑动时,会中断此事件,当手指上下滑动时,
会传递此事件,在onInterceptTouchEvent的action_down中,将此事件
传递给了手势识别器,因为当onInterceptTouchEvent返回true时,会将此事件传递给自己的
onTouchEvent进行处理,在onTouchEvent中收不到action_down消息,因此onInterceptTouchEvent
中将event事件传递给手势识别器。