android中的每个ViewGroup的子类都具有三个和TouchEvent相关的方法:
1.public boolean dispatchTouchEvent(MotionEvent event) 这个方法用来分发TouchEvent
2.public boolean onInterceptTouchEvent(MotionEvent event) 这个方法用来拦截TouchEvent
3.public boolean onTouchEvent(MotionEvent event) 这个方法用来处理TouchEvent
注意:不是所有的View的子类,只有可以向里面添加View的控件才需要分发,比如TextView它本身就是最小的view了,所以不用再向它的子视图分发了,它也没有子视图了,所以它没有dispatch和Intercept,只有touchEvent。举一个简单的例子:(一个activity,布局中有一个button)
对button进行监听
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("TAG", " onClick");
}
});
button.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("TAG", "onTouch " + event.getAction());
return false;
}
});
执行结果如下:
onTouch 0 相当与down
onTouch 1 相当于up
onClick 点击事件
由上面的结果可以看出来:事件传递的顺序是先经过onTouch,再传递到onClick
当onTouch return false说明你还没消费onTouch事件,在执行完你onTouch里面的代码之后,onTouch事件并没有结束
当onTouch return true时说明此次事件被onTouch给消费掉了,不会继续向下传递了
接着看dispatchTouchEvent的源码
/**
* Pass the touch screen motion event down to the target view, or this
* view if it is the target.
* @param event The motion event to be dispatched.
* @return True if the event was handled by the view, false otherwise.
*/
public boolean dispatchTouchEvent(MotionEvent event) {
if (!onFilterTouchEventForSecurity(event)) {
return false;
}
if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
mOnTouchListener.onTouch(this, event)) {
return true;
}
return onTouchEvent(event);
}
1.
OnTouchListener是在setOnTouchListener方法中设置的,事实上就是我们刚才在Activity中设置的setOnTouchListener,也就是说只要我们给控件注册了touch事件,mOnTouchListener就一定被赋值了
2.第二个条件是判断控件是否是使能的,按钮默认即使Enabled,所以为true
3.第三个条件是关键,该条件会回调控件注册touch事件时的onTouch方法,这里关键就是看onTouch方法执行的返回值
还有一点要题型的是Touch事件的层级传递。如果给一个控件注册了touch事件,每次点击它的时候都会触发一系列ACTION_DOWN,ACTION_MOVE,ACTION_UP等事件.如果你在执行ACTION_DOWN的时候返回了false,后面一系列其它的action就不会再得到执行了。简单的说,就是当dispatchTouchEvent在进行事件分发的时候,只有前一个action返回true,才会触发后一个action。