Last active
August 29, 2015 14:13
-
-
Save colinmadere/9b577871d015778b1497 to your computer and use it in GitHub Desktop.
CooperativeScrollGestureListener
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.view.GestureDetector; | |
import android.view.MotionEvent; | |
import android.view.ViewGroup; | |
/** | |
* Detects if scroll gesture happens, and if the secondary (often, the "inner" scrollable is at the | |
* edge in the direction the gesture is in, have the primary scrollable process the gesture | |
*/ | |
public class CooperativeScrollGestureListener implements GestureDetector.OnGestureListener { | |
private boolean isInGesture = false; | |
private boolean isScrollingVertical = false; | |
private ViewGroup mPrimaryView; | |
private ICoopInnerScrollableView mSecondaryView; | |
private GestureDetector mGestureDetector; | |
/** | |
* You may pass in 'null' for the 'secondaryView' parameter if you do NOT want the outer view | |
* to scroll when you hit the top/bottom of the inner scroll view. This will still make the | |
* inner scroll work when inside an outer scrollable view. | |
* @param ctx | |
* @param primaryView Usually the "outer" scrollable view you want cooperating | |
* @param secondaryView Usually the "inner" scrollable view you want cooperating (null = ignore overscroll) | |
*/ | |
public CooperativeScrollGestureListener(Context ctx, ViewGroup primaryView, ICoopInnerScrollableView secondaryView) { | |
mPrimaryView = primaryView; | |
mSecondaryView = secondaryView; | |
mGestureDetector = new GestureDetector(ctx, this); | |
} | |
@Override | |
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { | |
if (!isInGesture) { | |
isInGesture = true; | |
isScrollingVertical = (Math.abs(distanceY) > Math.abs(distanceX)); | |
} | |
if (!isScrollingVertical) return false; | |
if (distanceY < 0 && null != mSecondaryView && mSecondaryView.isScrollableAtTop()) { | |
// VIEW GOING UP | |
mPrimaryView.requestDisallowInterceptTouchEvent(false); | |
} else if (distanceY > 0 && null != mSecondaryView && mSecondaryView.isScrollableAtBottom()) { | |
// VIEW GOING DOWN | |
mPrimaryView.requestDisallowInterceptTouchEvent(false); | |
} else { | |
// Pulling up but at bottom of secondary view OR pulling down and at top of secondary view | |
mPrimaryView.requestDisallowInterceptTouchEvent(true); | |
} | |
return false; | |
} | |
// This MUST return true for DOWN event to have this see subsequent events | |
@Override | |
public boolean onDown(MotionEvent e) { | |
isInGesture = false; | |
isScrollingVertical = true; | |
return true; | |
} | |
@Override | |
public void onShowPress(MotionEvent e) { | |
// nothing | |
} | |
@Override | |
public boolean onSingleTapUp(MotionEvent e) { | |
isInGesture = false; | |
isScrollingVertical = false; | |
return false; | |
} | |
@Override | |
public void onLongPress(MotionEvent e) { | |
// nothing | |
} | |
@Override | |
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { | |
return false; | |
} | |
// ---------------------- methods ----------------------- | |
/** | |
* Your Activity must call this in it's dispatchTouchEvent() override. | |
* @param ev | |
*/ | |
public void dispatchTouchEvent(MotionEvent ev) { | |
mGestureDetector.onTouchEvent(ev); | |
} | |
/** | |
* The scrollable views (ScrollView, ListView, etc) should be wrapped in this interface to be | |
* generically handled by this listener. The operations done in these methods calls should | |
* not be computationally intensive since it would otherwise affect scrolling performance. | |
*/ | |
public interface ICoopInnerScrollableView { | |
public boolean isScrollableAtTop(); | |
public boolean isScrollableAtBottom(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment