问题描述:
开发中发现,SwipeRefreshLayout的下拉刷新与ViewPager的左右滑动存在冲突,导致ViewPager的左右滑动不灵敏。
原因分析:
通过查看ViewPager的源代码发现其实ViewPager在 onInterceptTouchEvent(MotionEvent ev)
方法的MotionEvent.ACTION_MOVE中做了处理,就是如果是左右滑动就请求父控件不要拦截手势(下图红框的部份)
那么这个方法为什么在SwipeRefreshLayout里就无效了呢??
接下来我们再看一下SwipeRefreshLayout的requestDisallowInterceptTouchEvent(booleanb)
方法你会发现SwipeRefreshLayout重写了该方法,并把它过滤掉了//Nope. 什么都不做
到此我们终于找到原因了,其实是SwipeRefreshLayout控件不允许子控件去禁止它的事件拦截
解决方案:
既然SwipeRefreshLayout控件不允许子控件禁止它的事件拦截,那么只要想办法让它允许子控件去禁止它的事件拦截不就完事了嘛!
OK!接下来就开始撸代码吧!
public class ViewPagerSwipeRefreshLayout extends SwipeRefreshLayout { private boolean disallowIntercept; public ViewPagerSwipeRefreshLayout(Context context) { this(context, null); } public ViewPagerSwipeRefreshLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { final int action = MotionEventCompat.getActionMasked(ev); if(action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { disallowIntercept = false; } //如果子控件请求不要拦截这个手势,那么就直接返回false,不拦截它的事件 if(disallowIntercept) { return false; } return super.onInterceptTouchEvent(ev); } @Override public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
//disallowIntercept为true代表子控件请求父控件不要拦截这个事件 this.disallowIntercept = disallowIntercept; super.requestDisallowInterceptTouchEvent(disallowIntercept); } }