如题,当SwipeRefreshLayout包裹ViewPager时,发现ViewPager经常滑不动,容易把上面的刷新的小圈圈拽出来,只有手指在屏幕上向斜上方滑或者水平滑动,才能保持正常,这是一个滑动冲突问题。

首先上网查一下别人怎么解决的

好像都是这个解决方案:

viewPager.setOnTouchListener(new View.OnTouchListener() {

      public boolean (View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
swipeRefreshLayout.setEnabled(false);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
swipeRefreshLayout.setEnabled(true);
break;
}
return false;
}
});

问题

嗯,代码看起来很美好,但是运行的时候发现,当下拉的手速比较慢时,刷新不能用了,说明SwipeRefreshLayout没有拦截到事件,然后到ViewPager这儿,就被禁用了。 其实看一下SwipeRefreshLayout的源码就能发现问题:
在SwipeRefreshLayout的构造器里有这么一句

mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop()

然后在onInterceptTouchEvent()方法中有这么一段:

final float yDiff = y - mInitialDownY;
if (yDiff > mTouchSlop && !mIsBeingDragged) {
mInitialMotionY = mInitialDownY + mTouchSlop;
mIsBeingDragged = true;
mProgress.setAlpha(STARTING_PROGRESS_ALPHA);
}

好了,问题如此清晰明了,当我们下拉的时候比较慢,第一次手指在y轴滑动的距离还不够mTouchSlop那么长,所以没有拦截,那viewpager秒秒钟给它禁掉了,因为我们在上面重写了ViewPager的触摸事件,之后yDiff的距离够长了,但是它已经被禁掉啊,然后就会出现只有一个半透明的小球滑下来,然后收上去了,什么也没发生……

解决方案

其实,这个滑动冲突的问题的关键在于,当手指向斜下方滑动时,手指在屏幕上移动的x轴的距离大于y轴的距离,这个时候我们是想让viewpager响应的,那重写SwipeRefreshLayout的onInterceptTouchEvent()方法就好了啊,当滑动X轴的距离大于Y轴的距离就让SwipeRefreshLayout不要拦截事件,完整的代码如下:

public 大专栏  ViewPager 和 SwipeRefreshLayout 的滑动冲突yword">class ReformSwipRefreshLayout extends SwipeRefreshLayout {
private float startY;
private float startX; private boolean mIsDraggingFlag;
private final int mTouchSlop; public ReformSwipRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
} public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
startY = ev.getY();
startX = ev.getX();
// 初始化标记
mIsDraggingFlag = false;
break;
case MotionEvent.ACTION_MOVE:
// 如果子view正在拖拽中,则不拦截
if(mIsDraggingFlag) {
return false;
}
float endY = ev.getY();
float endX = ev.getX();
float distanceX = Math.abs(endX - startX);
float distanceY = endY - startY;
// 如果X轴位移大于Y轴位移或者Y轴位移为负数时,事件交给子View处理
if(distanceX > mTouchSlop && distanceX>distanceY) {
mIsDraggingFlag = true;
return false;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// 初始化标记
mIsDraggingFlag = false;
break;
}
return super.onInterceptTouchEvent(ev);
} }

最新文章

  1. 第五篇:在SOUI中使用XML布局属性指引(pos, offset, pos2type)
  2. mongodb sharding 简单部署记录
  3. Tomcat服务启动成功,但访问index.jsp出错 (jspInit)
  4. 移动端 css实现自适应正圆 ( 宽高随着手机屏幕宽度自适应 )
  5. <context-param>与<init-param>
  6. 【07_226】Invert Binary Tree
  7. iOS百度地图探索
  8. Listview异步加载之优化篇
  9. leetcode@ [131/132] Palindrome Partitioning & Palindrome Partitioning II
  10. linux管理文件系统指令
  11. shell中的expr命令
  12. OS X 平台的 8 个实用终端工具
  13. BZOJ_2393_Cirno的完美算数教室&&BZOJ_1853_[Scoi2010]幸运数字 _深搜+容斥原理
  14. [Leetcode]827.使用回溯+标记解决最大人工岛问题
  15. koa 微信小程序 项目
  16. Apache+Tomcat负载均衡集群搭建
  17. redis的过期策略以及内存淘汰机制
  18. Shr-前端汇总
  19. 延长SSH的连接时间并重启ssh服务
  20. CNN结构

热门文章

  1. Python合成GIF图片 -- imageio库
  2. 干货 | 云解析DNS之网站监控
  3. day62-html-标签
  4. ubuntu19.10安装cuda-10.1
  5. ubuntu18安装pytorch1.3
  6. 《深入理解java虚拟机》-目录结构
  7. 六、Shell脚本高级编程实战第六部
  8. 37)智能指针(就是自动delete空间)
  9. UserTokenManager JwtHelper
  10. k8s miniKube 入门