onInterceptTouchEvent() 方法和 onTouchEvent() 的区别:
The onInterceptTouchEvent() method is called whenever a touch event is detected on the surface of a ViewGroup, including on the surface of its children. If onInterceptTouchEvent() returns true, the MotionEvent is intercepted, meaning it will be not be passed on to the child, but rather to the onTouchEvent() method of the parent.
翻译成大白话就是:
onInterceptTouchEvent() 方法如果你的返回值是true,那么这个触摸事件我们就把它拦截了,他里面的子view就没办法获取到这个事件了(不管你摸的是不是他的子view,只要你摸的地方在这个viewgroup范围内)。
然后这个事件就传到viewgroup的onTouchEvent()方法里了,在这里你可以根据滑动的距离想干嘛干嘛,你viewgroup里的子view永远都得不到这个事件了。
来段代码理解下:
在下面的代码里,我们写一个MyViewGroup继承自ViewGroup。MyViewGroup里面可能会包含几个子view。如果你干净的小手在在上面水平滑动,我们就不让子view得到这个触摸事件,让MyViewGroup来处理这个事件(也就是看上去里面的内容滑动了一下)。如果你按下了子view里的button,或者竖直的滑动了里面的子view,那么我们的viewgroup就不应该拦截这个事件了,因为我们的目的是按里面的按钮。在这种情况下,onInterceptTouchEvent()就应该返回false了,而且viewgroup的onTouchEvent()方法也不会被调用。
public class MyViewGroup extends ViewGroup {
private int mTouchSlop;
private float mDownX;
//手指刚落下的坐标,用来计算滑动距离的
...
ViewConfiguration vc = ViewConfiguration.get(view.getContext());
mTouchSlop = vc.getScaledTouchSlop();
//获得最小有效滑动距离(系统自带的方法)
...
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
/*
* 这个方法决定了我们是不是要拦截这个触摸事件
* 如果返回true,onTouchEvent()就会被调用
*/
final int action = MotionEventCompat.getActionMasked(ev);
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
// 如果这个触摸被取消了,或者手指抬起来了
mIsScrolling = false;
return false; // 返回false,不拦截事件,交给子view
}
switch (action) {
case MotionEvent.ACTION_MOVE: {
if (mIsScrolling) {
// 我们正在滑动呢,所以赶紧拦截下来吧
return true;
}
// 这个计算方法谷歌很不厚道的留给了读者自行解决。。。译者改天自己补上吧。。
final int xDiff = calculateDistanceX(ev);
//如果滑动距离大于最小有效距离,那么就拦截下来
if (xDiff > mTouchSlop) {
mIsScrolling = true;
return true;
}
break;
case MotionEvent.ACTION_DOWN:
//手指落下时的坐标,用来计算滑动距离的
mDownX = ev.getRawX();
return false;
}
...
}
//其他情况下我们就不拦截触摸事件了,交给子view处理这个触摸事件
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// 在这我们真正的开始处理滑动事件
//(例如 if ( ev.getAction() == ACTION_MOVE)
//{想干嘛干嘛}
//注意这个方法只有在 onInterceptTouchEvent返回true的时候才被调用(敲黑板!)
...
}
//补上补上
private int calculateDistanceX(MotionEvent ev) {
return (int) (ev.getRawX() - mDownX);
}
}
原创翻译,转载请注明http://blog.youkuaiyun.com/sinat_31598337
联系我:Joeys苏