AndroidSwipeRefreshLayout+ViewPager+ScrollView 滑动冲突解决

xiaoxiao2021-02-28  100

*项目中用到了SwipeRefreshLayout+ViewPager(轮播图)+ScrollView的组合,发现滑动效果很不友好,只有在水平的情况下viewpager才会滑动.影响用户体验. 首先可以确认是滑动冲突产生的影响. 个人因为是Viewpager出现的问题,我重写了ViewPager,当Y轴变化量大于X轴变化量时,对外一个监听,使其关闭其相应的滑动事件.发现时好时坏,有时手指刚刚触碰屏幕,抖动一下就会触发SwipeRefresh或ScrollView的触摸事件. 怀疑这两个的触摸事件比ScrollView的级别高(有兴趣可以查一下源码),那就在这两个空间上做文章,重写这两个控件,发现可行,下面上代码:*

重写SwipeRefreshLayout(出于google):

import android.content.Context; import android.support.v4.widget.SwipeRefreshLayout; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.ViewConfiguration; /** * Created by admin on 2017/5/5. */ public class MySwipeRefreshLayout extends SwipeRefreshLayout { private float startY; private float startX; // 记录viewPager是否拖拽的标记 private boolean mIsVpDragger; private final int mTouchSlop; public MySwipeRefreshLayout(Context context, AttributeSet attrs) { super(context, attrs); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: // 记录手指按下的位置 startY = ev.getY(); startX = ev.getX(); // 初始化标记 mIsVpDragger = false; break; case MotionEvent.ACTION_MOVE: // 如果viewpager正在拖拽中,那么不拦截它的事件,直接return false; if (mIsVpDragger) { return false; } // 获取当前手指位置 float endY = ev.getY(); float endX = ev.getX(); float distanceX = Math.abs(endX - startX); float distanceY = Math.abs(endY - startY); // 如果X轴位移大于Y轴位移,那么将事件交给viewPager处理。 if (distanceX > mTouchSlop && distanceX > distanceY) { mIsVpDragger = true; return false; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: // 初始化标记 mIsVpDragger = false; break; } // 如果是Y轴位移大于X轴,事件交给swipeRefreshLayout处理。 return super.onInterceptTouchEvent(ev); } }

重写ScrollView(出于google):

import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.ScrollView; /** * Created by admin on 2017/5/5. */ public class VerticalScrollView extends ScrollView { private float xDistance, yDistance, lastX, lastY; public VerticalScrollView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: xDistance = yDistance = 0f; lastX = ev.getX(); lastY = ev.getY(); break; case MotionEvent.ACTION_MOVE: final float curX = ev.getX(); final float curY = ev.getY(); xDistance += Math.abs(curX - lastX); yDistance += Math.abs(curY - lastY); lastX = curX; lastY = curY; if (xDistance > yDistance) return false; } return super.onInterceptTouchEvent(ev); } }
转载请注明原文地址: https://www.6miu.com/read-34138.html

最新回复(0)