diff options
| author | Chris Banes <chrisbanes@google.com> | 2015-10-23 13:42:06 +0100 |
|---|---|---|
| committer | Chris Banes <chrisbanes@google.com> | 2015-10-23 14:00:59 +0100 |
| commit | fc60a78760589b76087e2973add98d0aa35d50ab (patch) | |
| tree | 1727addf8839c32860bb3d629aa1505436884f79 /v4/java/android | |
| parent | 2e659d2367fc800cad5075c380d13df65ff36254 (diff) | |
| download | android_frameworks_support-fc60a78760589b76087e2973add98d0aa35d50ab.tar.gz android_frameworks_support-fc60a78760589b76087e2973add98d0aa35d50ab.tar.bz2 android_frameworks_support-fc60a78760589b76087e2973add98d0aa35d50ab.zip | |
Make SwipeRefreshLayout play nice with AppBarLayout
Currently SwipeRefreshLayout has support for nested scrolling,
but still relies on it's own touch handling, which conflicts.
This CL fixes it by disabling the touch handling when a nested
scroll is happening.
BUG: 25209946
Change-Id: I812f67e35753d243937a34a212cb1112065bff10
Diffstat (limited to 'v4/java/android')
| -rw-r--r-- | v4/java/android/support/v4/widget/SwipeRefreshLayout.java | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/v4/java/android/support/v4/widget/SwipeRefreshLayout.java b/v4/java/android/support/v4/widget/SwipeRefreshLayout.java index a5365e3bc1..e1386abc24 100644 --- a/v4/java/android/support/v4/widget/SwipeRefreshLayout.java +++ b/v4/java/android/support/v4/widget/SwipeRefreshLayout.java @@ -102,6 +102,7 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare private boolean mRefreshing = false; private int mTouchSlop; private float mTotalDragDistance = -1; + // If nested scrolling is enabled, the total amount that needed to be // consumed by this as the nested scrolling parent is used in place of the // overscroll determined by MOVE events in the onTouch handler @@ -109,6 +110,8 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare private final NestedScrollingParentHelper mNestedScrollingParentHelper; private final NestedScrollingChildHelper mNestedScrollingChildHelper; private final int[] mParentScrollConsumed = new int[2]; + private final int[] mParentOffsetInWindow = new int[2]; + private boolean mNestedScrollInProgress; private int mMediumAnimationDuration; private int mCurrentTargetOffsetTop; @@ -654,7 +657,8 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare mReturningToStart = false; } - if (!isEnabled() || mReturningToStart || canChildScrollUp() || mRefreshing) { + if (!isEnabled() || mReturningToStart || canChildScrollUp() + || mRefreshing || mNestedScrollInProgress) { // Fail fast if we're not in a state where a swipe is possible return false; } @@ -728,20 +732,18 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare @Override public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) { - if (isEnabled() && !mReturningToStart && !canChildScrollUp() && !mRefreshing - && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0) { - // Dispatch up to the nested parent - startNestedScroll(nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL); - return true; - } - return false; + return isEnabled() && !mReturningToStart && !mRefreshing + && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0; } @Override public void onNestedScrollAccepted(View child, View target, int axes) { // Reset the counter of how much leftover scroll needs to be consumed. mNestedScrollingParentHelper.onNestedScrollAccepted(child, target, axes); + // Dispatch up to the nested parent + startNestedScroll(axes & ViewCompat.SCROLL_AXIS_VERTICAL); mTotalUnconsumed = 0; + mNestedScrollInProgress = true; } @Override @@ -785,6 +787,7 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare @Override public void onStopNestedScroll(View target) { mNestedScrollingParentHelper.onStopNestedScroll(target); + mNestedScrollInProgress = false; // Finish the spinner for nested scrolling if we ever consumed any // unconsumed nested scroll if (mTotalUnconsumed > 0) { @@ -796,15 +799,22 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare } @Override - public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, - int dyUnconsumed) { - if (dyUnconsumed < 0) { - dyUnconsumed = Math.abs(dyUnconsumed); - mTotalUnconsumed += dyUnconsumed; + public void onNestedScroll(final View target, final int dxConsumed, final int dyConsumed, + final int dxUnconsumed, final int dyUnconsumed) { + // Dispatch up to the nested parent first + dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, + mParentOffsetInWindow); + + // This is a bit of a hack. Nested scrolling works from the bottom up, and as we are + // sometimes between two nested scrolling views, we need a way to be able to know when any + // nested scrolling parent has stopped handling events. We do that by using the + // 'offset in window 'functionality to see if we have been moved from the event. + // This is a decent indication of whether we should take over the event stream or not. + final int dy = dyUnconsumed + mParentOffsetInWindow[1]; + if (dy < 0) { + mTotalUnconsumed += Math.abs(dy); moveSpinner(mTotalUnconsumed); } - // Dispatch up to the nested parent - dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dxConsumed, null); } // NestedScrollingChild @@ -961,7 +971,7 @@ public class SwipeRefreshLayout extends ViewGroup implements NestedScrollingPare mReturningToStart = false; } - if (!isEnabled() || mReturningToStart || canChildScrollUp()) { + if (!isEnabled() || mReturningToStart || canChildScrollUp() || mNestedScrollInProgress) { // Fail fast if we're not in a state where a swipe is possible return false; } |
