前几天在自定义viewgroup的时候一直无法触发事件,后来发现是事件会默认向下传递,需要拦截事件由自己触发.
下面粘贴一些log的事件大家可以自己去看log来理解就会非常好理解的:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "dispatchTouchEvent ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "dispatchTouchEvent ACTION_UP");
break;
default:
break;
}
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "onTouchEvent ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "onTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "onTouchEvent ACTION_UP");
break;
default:
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action =event.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "onInterceptTouchEvent ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "onInterceptTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "onInterceptTouchEvent ACTION_UP");
break;
default:
break;
}
return super.onTouchEvent(event);
}
类似下面这个列子:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mXDown = ev.getRawX();
mXLastMove = mXDown;
break;
case MotionEvent.ACTION_MOVE:
mXMove = ev.getRawX();
float diff = Math.abs(mXMove - mXDown);
mXLastMove = mXMove;
// 当手指拖动值大于TouchSlop值时,认为应该进行滚动,拦截子控件的事件
if (diff > mTouchSlop) {
return true;
}
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (tracker == null) {
tracker = VelocityTracker.obtain();
}
tracker.addMovement(event);
//scroller.startScroll();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downposition = (int) event.getX();
// scrollTo();
Log.e(TAG, "onTouchEvent: down" + downposition);
break;
case MotionEvent.ACTION_MOVE:
moveposition = (int) event.getX();
Log.e(TAG, "onTouchEvent: move" + moveposition);
position = moveposition - downposition;
//if (position>mTouchSlop) {
// currentposition += position;
// }
scrollTo(currentposition -position, 0);
break;
case MotionEvent.ACTION_UP:
currentposition -= position;
tracker.computeCurrentVelocity(1000);
scroller.fling(currentposition, 0, -((int) tracker.getXVelocity()), 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0);
invalidate();
break;
}
return true;
}
当我在拦截方法中
onInterceptTouchEvent
的down事件中不return true
ontouch方法中的down事件就不会触发因为事件传到子控件中去了。
当onintercepttouchevent中的actionmove的事件中return true时该控件会拦截事件向下传递从而
在自己的ontouch方法中执行move的action方法。
以上大概就是在viewgroup中拦截事件的方法。
在viewgroup中执行的顺序依次是
dispatchTouchEvent然后onInterceptTouchEvent然后是onTouchEvent
还有一种情况是子控件向上传递的事件,传递到子控件,子控件的ontouch returnfalse不处理事件就会返回上级去找处理事件的方法
这种情况我没有研究过了解就行了。