SwipeLayout: Allow childs to deny swipe gesture

When used with ScorllView(or horizontal) inside SwipeLayout, the swipe
gesture may conflict with the scroll action. If use requestDisallowInterceptTouchEvent, the scroll action will be back but the parent ListView's scroll action may be disallowed too.

This patch solved this problem by introducing a "SwipeDenier"
interface whose implementation should return if this swipe event should
be denied. When onInterceptTouchEvent is called, SwipeLayout will call
all SwipeDenier and if one of them returns true, the event will not be
intercepted and passed to child views.

Tested in app: https://github.com/PaperAirplane-Dev-Team/BlackLight
which requires HorizontalScrollView inside SwipeLayout

Signed-off-by: Peter Cai <xqsx43cxy@126.com>
This commit is contained in:
Peter Cai 2014-08-29 16:46:21 +08:00
parent 7d7752b39f
commit 7425e3c68c
1 changed files with 32 additions and 0 deletions

View File

@ -28,6 +28,7 @@ public class SwipeLayout extends FrameLayout {
private ShowMode mShowMode;
private List<SwipeListener> mSwipeListeners = new ArrayList<SwipeListener>();
private List<SwipeDenier> mSwipeDeniers = new ArrayList<SwipeDenier>();
private Map<View, ArrayList<OnRevealListener>> mRevealListeners = new HashMap<View, ArrayList<OnRevealListener>>();
private Map<View, Boolean> mShowEntirely = new HashMap<View, Boolean>();
@ -82,6 +83,31 @@ public class SwipeLayout extends FrameLayout {
mSwipeListeners.clear();
}
public static interface SwipeDenier {
/*
* Called in onInterceptTouchEvent
* Determines if this swipe event should be denied
* Implement this interface if you are using views with swipe gestures
* As a child of SwipeLayout
*
* @return true deny
* false allow
*/
public boolean shouldDenySwipe(MotionEvent ev);
}
public void addSwipeDenier(SwipeDenier denier) {
mSwipeDeniers.add(denier);
}
public void removeSwipeDenier(SwipeDenier denier) {
mSwipeDeniers.remove(denier);
}
public void removeAllSwipeDeniers() {
mSwipeDeniers.clear();
}
public interface OnRevealListener {
public void onReveal(View child, DragEdge edge, float fraction, int distance);
}
@ -615,6 +641,12 @@ public class SwipeLayout extends FrameLayout {
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
for (SwipeDenier denier : mSwipeDeniers) {
if (denier != null && denier.shouldDenySwipe(ev)) {
return false;
}
}
return mDragHelper.shouldInterceptTouchEvent(ev);
}