SwipeRefreshLayout中的Horizo​​ntalScrollView

我在我的应用程序中实现了新的SwipeRefreshLayout组件,并且它适用于任何垂直视图,如ListViewGridViewScrollView

水平视图的行为非常糟糕,比如HorizontalScrollView 。 当滚动到右侧或左侧时, SwipeRefreshLayout视图caching触摸,防止HorizontalScrollView接收并垂直滚动以执行刷新。

我试着解决这个问题,因为我以前用ViewPager解决垂直ScrollView问题,使用requestDisallowInterceptTouchEvent但它没有工作。 我也注意到这个方法在原来的SwipeRefreshLayout类中被覆盖而没有返回超类。 谷歌的开发人员留下了一个评论,而不是“/ / //Nope.

由于SwipeRefreshLayout组件是相对较新的,我找不到一个解决scheme,修复了水平滚动问题,同时仍然允许刷新视图来跟踪和处理垂直滚动,所以我想我会分享我的解决scheme,希望它会让别人一两个小时。

我通过扩展SwipeRefreshLayout并覆盖onInterceptTouchEvent来解决这个问题。 在里面,我计算用户漫游的X距离是否大于触摸斜坡。 如果是这样,则表示用户正在水平滑动,因此我返回false ,让子视图(本例中为HorizontalScrollView )获取触摸事件。

 public class CustomSwipeToRefresh extends SwipeRefreshLayout { private int mTouchSlop; private float mPrevX; public CustomSwipeToRefresh(Context context, AttributeSet attrs) { super(context, attrs); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } @Override public boolean onInterceptTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mPrevX = MotionEvent.obtain(event).getX(); break; case MotionEvent.ACTION_MOVE: final float eventX = event.getX(); float xDiff = Math.abs(eventX - mPrevX); if (xDiff > mTouchSlop) { return false; } } return super.onInterceptTouchEvent(event); } } 

如果您不记得您已经拒绝ACTION_MOVE事件的事实,那么稍后如果用户回到最初的mPrevX附近,您将最终采取这一行动。

只需添加一个布尔值来记住它。

 public class CustomSwipeToRefresh extends SwipeRefreshLayout { private int mTouchSlop; private float mPrevX; // Indicate if we've already declined the move event private boolean mDeclined; public CustomSwipeToRefresh(Context context, AttributeSet attrs) { super(context, attrs); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } @Override public boolean onInterceptTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mPrevX = MotionEvent.obtain(event).getX(); mDeclined = false; // New action break; case MotionEvent.ACTION_MOVE: final float eventX = event.getX(); float xDiff = Math.abs(eventX - mPrevX); if (mDeclined || xDiff > mTouchSlop) { mDeclined = true; // Memorize return false; } } return super.onInterceptTouchEvent(event); } } 

如果您使用Tim Roes EnhancedListView

看到这个问题 。 我对我来说非常有用,因为他们添加了一个function,可以检测刷卡什么时候开始,什么时候刷卡结束。

当滑动开始时,我禁用了SwipeRefreshLayout,当刷卡完成时,我可以使用swipeRefreshLayout。