例子:一个跟手滑动TextView,重写了OnTouchListener.onTouch方法,当该方法返回false时textView不会跟手滑动,返回true才可以
textView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int nowX = (int) event.getRawX();
int nowY = (int) event.getRawY();
int left, top;
mLayoutWidth = frameLayout.getWidth();
mLayoutHeight = frameLayout.getHeight();
Log.e("lingshaofu", "OnTouchListener.onTouch事件类型为:" + event.getAction());//打log
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastMoveX = nowX;
lastMoveY = nowY;
break;
case MotionEvent.ACTION_MOVE:
int deltaX = nowX - lastMoveX;
int deltaY = nowY - lastMoveY;
int tempLeft = v.getLeft() + deltaX;
int tempTop = v.getTop() + deltaY;
if (tempLeft < 0) {
left = 0;
} else if (tempLeft > mLayoutWidth - v.getWidth()) {
left = mLayoutWidth - v.getWidth();
} else {
left = tempLeft;
}
if (tempTop < 0) {
top = 0;
} else if (tempTop > mLayoutHeight - v.getHeight()) {
top = mLayoutHeight - v.getHeight();
} else {
top = tempTop;
}
v.layout(left, top, left + v.getWidth(), top + v.getHeight());
break;
case MotionEvent.ACTION_UP:
break;
}
lastMoveX = nowX;
lastMoveY = nowY;
return false;
}
});
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.e("lingshaofu", "onTouchEvent事件类型为:" + event.getAction());
return true;
}
1、调用顺序,OnTouchListener.onTouch()——>onTouchEvent()——>OnClickListener.onClick(),其中若onTouch返回值为true,则会屏蔽掉onTouchEvent方法和OnClickListener.onClick方法,若onTouchEvent方法可以被调用,则OnClickListener.onClick方法也一定可以被调用。
2、一系列点击事件,肯定是以down事件开始,以up事件结束,中间若干个move事件。如果一旦某个元素拦截了某个事件,那么同一个事件序列内的所有事件都会直接交给它处理。(详见Android开发艺术探索P142)
3、首先,考虑OnTouchListener.onTouch返回的是false,此种情况下,首先down事件按照顺序先经过OnTouchListener.onTouch方法,由于返回false不屏蔽onTouchEvent方法,所以又被分发到onTouchEvent方法,由于该方法默认返回true(详见Android开发艺术探索P143),即消费了down事件,所以此后的所有事件都由该方法处理,并且不再经过OnTouchListener.onTouch。可以看下图log证实了这点,当手指试图滑动时,down事件分别经过两个方法,其他的事件只经过onTouchEvent
当返回true时,滑动时截图如下,可以看到,并没有调用onTouchEvent方法