Loading core/java/android/widget/AbsListView.java +57 −35 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te ViewTreeObserver.OnTouchModeChangeListener, RemoteViewsAdapter.RemoteAdapterConnectionCallback { @SuppressWarnings("UnusedDeclaration") private static final String TAG = "AbsListView"; /** Loading Loading @@ -2429,7 +2430,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final ViewTreeObserver treeObserver = getViewTreeObserver(); treeObserver.removeOnTouchModeChangeListener(this); if (mTextFilterEnabled && mPopup != null) { treeObserver.removeGlobalOnLayoutListener(this); treeObserver.removeOnGlobalLayoutListener(this); mGlobalLayoutListenerAddedFilter = false; } Loading Loading @@ -2943,11 +2944,23 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mDirection = 0; // Reset when entering overscroll. mTouchMode = TOUCH_MODE_OVERSCROLL; if (rawDeltaY > 0) { if (!mEdgeGlowTop.isIdle()) { invalidate(mEdgeGlowTop.getBounds()); } else { invalidate(); } mEdgeGlowTop.onPull((float) overscroll / getHeight()); if (!mEdgeGlowBottom.isFinished()) { mEdgeGlowBottom.onRelease(); } } else if (rawDeltaY < 0) { if (!mEdgeGlowBottom.isIdle()) { invalidate(mEdgeGlowBottom.getBounds()); } else { invalidate(); } mEdgeGlowBottom.onPull((float) overscroll / getHeight()); if (!mEdgeGlowTop.isFinished()) { mEdgeGlowTop.onRelease(); Loading @@ -2956,7 +2969,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } mMotionY = y; invalidate(); } mLastY = y; } Loading Loading @@ -2990,25 +3002,25 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (!mEdgeGlowBottom.isFinished()) { mEdgeGlowBottom.onRelease(); } invalidate(mEdgeGlowTop.getBounds()); } else if (rawDeltaY < 0) { mEdgeGlowBottom.onPull((float) overScrollDistance / getHeight()); if (!mEdgeGlowTop.isFinished()) { mEdgeGlowTop.onRelease(); } invalidate(mEdgeGlowBottom.getBounds()); } invalidate(); } } if (incrementalDeltaY != 0) { // Coming back to 'real' list scrolling if (mScrollY != 0) { mScrollY = 0; invalidateParentIfNeeded(); } // No need to do all this work if we're not going to move anyway if (incrementalDeltaY != 0) { trackMotionScroll(incrementalDeltaY, incrementalDeltaY); } mTouchMode = TOUCH_MODE_SCROLL; Loading Loading @@ -3468,11 +3480,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final int rightPadding = mListPadding.right + mGlowPaddingRight; final int width = getWidth() - leftPadding - rightPadding; canvas.translate(leftPadding, Math.min(0, scrollY + mFirstPositionDistanceGuess)); int edgeY = Math.min(0, scrollY + mFirstPositionDistanceGuess); canvas.translate(leftPadding, edgeY); mEdgeGlowTop.setSize(width, getHeight()); if (mEdgeGlowTop.draw(canvas)) { invalidate(); mEdgeGlowTop.setPosition(leftPadding, edgeY); invalidate(mEdgeGlowTop.getBounds()); } canvas.restoreToCount(restoreCount); } Loading @@ -3483,12 +3496,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final int width = getWidth() - leftPadding - rightPadding; final int height = getHeight(); canvas.translate(-width + leftPadding, Math.max(height, scrollY + mLastPositionDistanceGuess)); int edgeX = -width + leftPadding; int edgeY = Math.max(height, scrollY + mLastPositionDistanceGuess); canvas.translate(edgeX, edgeY); canvas.rotate(180, width, 0); mEdgeGlowBottom.setSize(width, height); if (mEdgeGlowBottom.draw(canvas)) { invalidate(); // Account for the rotation mEdgeGlowBottom.setPosition(edgeX + width, edgeY - mEdgeGlowBottom.getHeight()); invalidate(mEdgeGlowBottom.getBounds()); } canvas.restoreToCount(restoreCount); } Loading Loading @@ -3874,7 +3890,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } // Don't stop just because delta is zero (it could have been rounded) final boolean atEnd = trackMotionScroll(delta, delta) && (delta != 0); final boolean atEdge = trackMotionScroll(delta, delta); final boolean atEnd = atEdge && (delta != 0); if (atEnd) { if (motionView != null) { // Tweak the scroll for how far we overshot Loading @@ -3889,7 +3906,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } if (more && !atEnd) { invalidate(); if (atEdge) invalidate(); mLastFlingY = y; post(this); } else { Loading Loading @@ -4431,7 +4448,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } private void createScrollingCache() { if (mScrollingCacheEnabled && !mCachingStarted) { if (mScrollingCacheEnabled && !mCachingStarted && !isHardwareAccelerated()) { setChildrenDrawnWithCacheEnabled(true); setChildrenDrawingCacheEnabled(true); mCachingStarted = mCachingActive = true; Loading @@ -4439,6 +4456,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } private void clearScrollingCache() { if (!isHardwareAccelerated()) { if (mClearScrollingCache == null) { mClearScrollingCache = new Runnable() { public void run() { Loading @@ -4457,6 +4475,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } post(mClearScrollingCache); } } /** * Track a motion scroll Loading Loading @@ -4599,14 +4618,18 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mRecycler.removeSkippedScrap(); } // invalidate before moving the children to avoid unnecessary invalidate // calls to bubble up from the children all the way to the top if (!awakenScrollBars()) { invalidate(); } offsetChildrenTopAndBottom(incrementalDeltaY); if (down) { mFirstPosition += count; } invalidate(); final int absIncrementalDeltaY = Math.abs(incrementalDeltaY); if (spaceAbove < absIncrementalDeltaY || spaceBelow < absIncrementalDeltaY) { fillGap(down); Loading @@ -4629,7 +4652,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mBlockLayoutRequests = false; invokeOnItemScrollListener(); awakenScrollBars(); return false; } Loading core/java/android/widget/EdgeEffect.java +44 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.widget; import android.graphics.Rect; import com.android.internal.R; import android.content.Context; Loading Loading @@ -45,6 +46,7 @@ import android.view.animation.Interpolator; * {@link #draw(Canvas)} method.</p> */ public class EdgeEffect { @SuppressWarnings("UnusedDeclaration") private static final String TAG = "EdgeEffect"; // Time it will take the effect to fully recede in ms Loading @@ -57,10 +59,7 @@ public class EdgeEffect { private static final int PULL_DECAY_TIME = 1000; private static final float MAX_ALPHA = 1.f; private static final float HELD_EDGE_ALPHA = 0.7f; private static final float HELD_EDGE_SCALE_Y = 0.5f; private static final float HELD_GLOW_ALPHA = 0.5f; private static final float HELD_GLOW_SCALE_Y = 0.5f; private static final float MAX_GLOW_HEIGHT = 4.f; Loading @@ -76,7 +75,9 @@ public class EdgeEffect { private final Drawable mGlow; private int mWidth; private int mHeight; private final int MIN_WIDTH = 300; private int mX; private int mY; private static final int MIN_WIDTH = 300; private final int mMinWidth; private float mEdgeAlpha; Loading Loading @@ -120,6 +121,8 @@ public class EdgeEffect { private float mPullDistance; private final Rect mBounds = new Rect(); /** * Construct a new EdgeEffect with a theme appropriate for the provided context. * @param context Context used to provide theming and resource information for the EdgeEffect Loading @@ -144,6 +147,29 @@ public class EdgeEffect { mHeight = height; } /** * Set the position of this edge effect in pixels. This position is * only used by {@link #getBounds()}. * * @param x The position of the edge effect on the X axis * @param y The position of the edge effect on the Y axis */ void setPosition(int x, int y) { mX = x; mY = y; } boolean isIdle() { return mState == STATE_IDLE; } /** * Returns the height of the effect itself. */ int getHeight() { return Math.max(mGlow.getBounds().height(), mEdge.getBounds().height()); } /** * Reports if this EdgeEffect's animation is finished. If this method returns false * after a call to {@link #draw(Canvas)} the host widget should schedule another Loading Loading @@ -301,7 +327,6 @@ public class EdgeEffect { update(); final int edgeHeight = mEdge.getIntrinsicHeight(); final int edgeWidth = mEdge.getIntrinsicWidth(); final int glowHeight = mGlow.getIntrinsicHeight(); final int glowWidth = mGlow.getIntrinsicWidth(); Loading Loading @@ -334,9 +359,23 @@ public class EdgeEffect { } mEdge.draw(canvas); if (mState == STATE_RECEDE && glowBottom == 0 && edgeBottom == 0) { mState = STATE_IDLE; } return mState != STATE_IDLE; } /** * Returns the bounds of the edge effect. */ public Rect getBounds() { mBounds.set(mGlow.getBounds()); mBounds.union(mEdge.getBounds()); mBounds.offset(mX, mY); return mBounds; } private void update() { final long time = AnimationUtils.currentAnimationTimeMillis(); final float t = Math.min((time - mStartTime) / mDuration, 1.f); Loading Loading
core/java/android/widget/AbsListView.java +57 −35 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te ViewTreeObserver.OnTouchModeChangeListener, RemoteViewsAdapter.RemoteAdapterConnectionCallback { @SuppressWarnings("UnusedDeclaration") private static final String TAG = "AbsListView"; /** Loading Loading @@ -2429,7 +2430,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final ViewTreeObserver treeObserver = getViewTreeObserver(); treeObserver.removeOnTouchModeChangeListener(this); if (mTextFilterEnabled && mPopup != null) { treeObserver.removeGlobalOnLayoutListener(this); treeObserver.removeOnGlobalLayoutListener(this); mGlobalLayoutListenerAddedFilter = false; } Loading Loading @@ -2943,11 +2944,23 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mDirection = 0; // Reset when entering overscroll. mTouchMode = TOUCH_MODE_OVERSCROLL; if (rawDeltaY > 0) { if (!mEdgeGlowTop.isIdle()) { invalidate(mEdgeGlowTop.getBounds()); } else { invalidate(); } mEdgeGlowTop.onPull((float) overscroll / getHeight()); if (!mEdgeGlowBottom.isFinished()) { mEdgeGlowBottom.onRelease(); } } else if (rawDeltaY < 0) { if (!mEdgeGlowBottom.isIdle()) { invalidate(mEdgeGlowBottom.getBounds()); } else { invalidate(); } mEdgeGlowBottom.onPull((float) overscroll / getHeight()); if (!mEdgeGlowTop.isFinished()) { mEdgeGlowTop.onRelease(); Loading @@ -2956,7 +2969,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } mMotionY = y; invalidate(); } mLastY = y; } Loading Loading @@ -2990,25 +3002,25 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (!mEdgeGlowBottom.isFinished()) { mEdgeGlowBottom.onRelease(); } invalidate(mEdgeGlowTop.getBounds()); } else if (rawDeltaY < 0) { mEdgeGlowBottom.onPull((float) overScrollDistance / getHeight()); if (!mEdgeGlowTop.isFinished()) { mEdgeGlowTop.onRelease(); } invalidate(mEdgeGlowBottom.getBounds()); } invalidate(); } } if (incrementalDeltaY != 0) { // Coming back to 'real' list scrolling if (mScrollY != 0) { mScrollY = 0; invalidateParentIfNeeded(); } // No need to do all this work if we're not going to move anyway if (incrementalDeltaY != 0) { trackMotionScroll(incrementalDeltaY, incrementalDeltaY); } mTouchMode = TOUCH_MODE_SCROLL; Loading Loading @@ -3468,11 +3480,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final int rightPadding = mListPadding.right + mGlowPaddingRight; final int width = getWidth() - leftPadding - rightPadding; canvas.translate(leftPadding, Math.min(0, scrollY + mFirstPositionDistanceGuess)); int edgeY = Math.min(0, scrollY + mFirstPositionDistanceGuess); canvas.translate(leftPadding, edgeY); mEdgeGlowTop.setSize(width, getHeight()); if (mEdgeGlowTop.draw(canvas)) { invalidate(); mEdgeGlowTop.setPosition(leftPadding, edgeY); invalidate(mEdgeGlowTop.getBounds()); } canvas.restoreToCount(restoreCount); } Loading @@ -3483,12 +3496,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te final int width = getWidth() - leftPadding - rightPadding; final int height = getHeight(); canvas.translate(-width + leftPadding, Math.max(height, scrollY + mLastPositionDistanceGuess)); int edgeX = -width + leftPadding; int edgeY = Math.max(height, scrollY + mLastPositionDistanceGuess); canvas.translate(edgeX, edgeY); canvas.rotate(180, width, 0); mEdgeGlowBottom.setSize(width, height); if (mEdgeGlowBottom.draw(canvas)) { invalidate(); // Account for the rotation mEdgeGlowBottom.setPosition(edgeX + width, edgeY - mEdgeGlowBottom.getHeight()); invalidate(mEdgeGlowBottom.getBounds()); } canvas.restoreToCount(restoreCount); } Loading Loading @@ -3874,7 +3890,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } // Don't stop just because delta is zero (it could have been rounded) final boolean atEnd = trackMotionScroll(delta, delta) && (delta != 0); final boolean atEdge = trackMotionScroll(delta, delta); final boolean atEnd = atEdge && (delta != 0); if (atEnd) { if (motionView != null) { // Tweak the scroll for how far we overshot Loading @@ -3889,7 +3906,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } if (more && !atEnd) { invalidate(); if (atEdge) invalidate(); mLastFlingY = y; post(this); } else { Loading Loading @@ -4431,7 +4448,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } private void createScrollingCache() { if (mScrollingCacheEnabled && !mCachingStarted) { if (mScrollingCacheEnabled && !mCachingStarted && !isHardwareAccelerated()) { setChildrenDrawnWithCacheEnabled(true); setChildrenDrawingCacheEnabled(true); mCachingStarted = mCachingActive = true; Loading @@ -4439,6 +4456,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } private void clearScrollingCache() { if (!isHardwareAccelerated()) { if (mClearScrollingCache == null) { mClearScrollingCache = new Runnable() { public void run() { Loading @@ -4457,6 +4475,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } post(mClearScrollingCache); } } /** * Track a motion scroll Loading Loading @@ -4599,14 +4618,18 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mRecycler.removeSkippedScrap(); } // invalidate before moving the children to avoid unnecessary invalidate // calls to bubble up from the children all the way to the top if (!awakenScrollBars()) { invalidate(); } offsetChildrenTopAndBottom(incrementalDeltaY); if (down) { mFirstPosition += count; } invalidate(); final int absIncrementalDeltaY = Math.abs(incrementalDeltaY); if (spaceAbove < absIncrementalDeltaY || spaceBelow < absIncrementalDeltaY) { fillGap(down); Loading @@ -4629,7 +4652,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mBlockLayoutRequests = false; invokeOnItemScrollListener(); awakenScrollBars(); return false; } Loading
core/java/android/widget/EdgeEffect.java +44 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.widget; import android.graphics.Rect; import com.android.internal.R; import android.content.Context; Loading Loading @@ -45,6 +46,7 @@ import android.view.animation.Interpolator; * {@link #draw(Canvas)} method.</p> */ public class EdgeEffect { @SuppressWarnings("UnusedDeclaration") private static final String TAG = "EdgeEffect"; // Time it will take the effect to fully recede in ms Loading @@ -57,10 +59,7 @@ public class EdgeEffect { private static final int PULL_DECAY_TIME = 1000; private static final float MAX_ALPHA = 1.f; private static final float HELD_EDGE_ALPHA = 0.7f; private static final float HELD_EDGE_SCALE_Y = 0.5f; private static final float HELD_GLOW_ALPHA = 0.5f; private static final float HELD_GLOW_SCALE_Y = 0.5f; private static final float MAX_GLOW_HEIGHT = 4.f; Loading @@ -76,7 +75,9 @@ public class EdgeEffect { private final Drawable mGlow; private int mWidth; private int mHeight; private final int MIN_WIDTH = 300; private int mX; private int mY; private static final int MIN_WIDTH = 300; private final int mMinWidth; private float mEdgeAlpha; Loading Loading @@ -120,6 +121,8 @@ public class EdgeEffect { private float mPullDistance; private final Rect mBounds = new Rect(); /** * Construct a new EdgeEffect with a theme appropriate for the provided context. * @param context Context used to provide theming and resource information for the EdgeEffect Loading @@ -144,6 +147,29 @@ public class EdgeEffect { mHeight = height; } /** * Set the position of this edge effect in pixels. This position is * only used by {@link #getBounds()}. * * @param x The position of the edge effect on the X axis * @param y The position of the edge effect on the Y axis */ void setPosition(int x, int y) { mX = x; mY = y; } boolean isIdle() { return mState == STATE_IDLE; } /** * Returns the height of the effect itself. */ int getHeight() { return Math.max(mGlow.getBounds().height(), mEdge.getBounds().height()); } /** * Reports if this EdgeEffect's animation is finished. If this method returns false * after a call to {@link #draw(Canvas)} the host widget should schedule another Loading Loading @@ -301,7 +327,6 @@ public class EdgeEffect { update(); final int edgeHeight = mEdge.getIntrinsicHeight(); final int edgeWidth = mEdge.getIntrinsicWidth(); final int glowHeight = mGlow.getIntrinsicHeight(); final int glowWidth = mGlow.getIntrinsicWidth(); Loading Loading @@ -334,9 +359,23 @@ public class EdgeEffect { } mEdge.draw(canvas); if (mState == STATE_RECEDE && glowBottom == 0 && edgeBottom == 0) { mState = STATE_IDLE; } return mState != STATE_IDLE; } /** * Returns the bounds of the edge effect. */ public Rect getBounds() { mBounds.set(mGlow.getBounds()); mBounds.union(mEdge.getBounds()); mBounds.offset(mX, mY); return mBounds; } private void update() { final long time = AnimationUtils.currentAnimationTimeMillis(); final float t = Math.min((time - mStartTime) / mDuration, 1.f); Loading