内部拦截法和外部拦截法
外部拦截法
ViewGroup可以拦截掉Move事件但是不能拦截掉Down事件,因为View
还要相应Down事件
在自定义ViewGroup里面重写 onInterceptTouchEvent(MotionEvent ev)方法
并对Move的移动进行拦截。
import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import java.lang.reflect.Field;
public class MySwipeRefreshLayout extends SwipeRefreshLayout {
private static final String TAG = "MySwipeRefreshLayout";
public MySwipeRefreshLayout(Context context) {
super(context);
}
public MySwipeRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
private float startX;
private float startY;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = ev.getX();
startY = ev.getY();
return false;
case MotionEvent.ACTION_MOVE:
float delX = Math.abs(ev.getX() - startX);
float delY = Math.abs(ev.getY() - startY);
//因为在move事件的时候,虽然子View设置了,getParent().requestDisallowInterceptTouchEvent(false);
//但是往下滑动的时候我们发现在SwipeRefreshLayout的源码中报了以下错误
//Got ACTION_MOVE event but don't have an active pointer id.
//报这个错误的原因是因为 if (this.mActivePointerId == -1) 这个条件成立
//所以我们需要想办法把这个属性改掉,由于SwipeRefreshLayout没有直接的API修改
//因此我想到了反射把mActivePointerId属性改成0
if ((delY - delX) > 0) {
Class clazz = getClass().getSuperclass();
Field field = null;
try {
field = clazz.getDeclaredField("mActivePointerId");
field.setAccessible(true);
field.setInt(this, 0);
Log.e(TAG, "onInterceptTouchEvent: 反射成功");
} catch (Exception e) {
Log.e(TAG, "onInterceptTouchEvent: 反射失败" + e.getMessage());
e.printStackTrace();
}
}
break;
}
return super.onInterceptTouchEvent(ev);
}
}
内部拦截法
import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
public class MyViewPager extends ViewPager {
private static final String TAG = "MyViewPager";
public MyViewPager(Context context) {
super(context);
}
public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
private float startX;
private float startY;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "子View: ACTION_DOWN");
getParent(). requestDisallowInterceptTouchEvent(true);
startX = ev.getX();
startY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
float delX = Math.abs(ev.getX() - startX);
float delY = Math.abs(ev.getY() - startY);
if (delX < delY) {
Log.e(TAG, "子View: 取消禁用拦截");
getParent().requestDisallowInterceptTouchEvent(false);
return false;
}
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "子View: ACTION_UP");
break;
case MotionEvent.ACTION_CANCEL:
Log.e(TAG, "子View: ACTION_CANCEL");
break;
}
return super.dispatchTouchEvent(ev);
}
}
网友评论