diff options
| author | 2010-07-01 13:45:58 -0700 | |
|---|---|---|
| committer | 2010-07-01 13:45:58 -0700 | |
| commit | 85e39f64e8ccfc31d5290e91fe2fa5ff5df273f6 (patch) | |
| tree | a5644706ca380ddad80bbbe8e85a8bc937ceb544 | |
| parent | 2ed26c4e5c5445e3f7d558dd3ff26ea44810344b (diff) | |
| parent | e44afae7ff91edb80142fc62ce2bc2cb9d133d09 (diff) | |
Merge "Add AbsListView#smoothScrollToPositionFromTop"
| -rw-r--r-- | api/current.xml | 15 | ||||
| -rw-r--r-- | core/java/android/widget/AbsListView.java | 78 |
2 files changed, 91 insertions, 2 deletions
diff --git a/api/current.xml b/api/current.xml index 192e0bf6329d..c6df75920453 100644 --- a/api/current.xml +++ b/api/current.xml @@ -205332,6 +205332,21 @@ <parameter name="boundPosition" type="int"> </parameter> </method> +<method name="smoothScrollToPositionFromTop" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="position" type="int"> +</parameter> +<parameter name="offset" type="int"> +</parameter> +</method> <method name="verifyDrawable" return="boolean" abstract="false" diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 10927a7524d5..1d5c5f944185 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -2541,6 +2541,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private static final int MOVE_UP_POS = 2; private static final int MOVE_DOWN_BOUND = 3; private static final int MOVE_UP_BOUND = 4; + private static final int MOVE_OFFSET = 5; private int mMode; private int mTargetPos; @@ -2548,6 +2549,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private int mLastSeenPos; private int mScrollDuration; private final int mExtraScroll; + + private int mOffsetFromTop; PositionScroller() { mExtraScroll = ViewConfiguration.get(mContext).getScaledFadingEdgeLength(); @@ -2639,11 +2642,37 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te post(this); } - + + void startWithOffset(int position, int offset) { + mTargetPos = position; + mOffsetFromTop = offset; + mBoundPos = INVALID_POSITION; + mLastSeenPos = INVALID_POSITION; + mMode = MOVE_OFFSET; + + final int firstPos = mFirstPosition; + final int lastPos = firstPos + getChildCount() - 1; + + int viewTravelCount = 0; + if (position < firstPos) { + viewTravelCount = firstPos - position; + } else if (position > lastPos) { + viewTravelCount = position - lastPos; + } else { + // On-screen, just scroll. + final int targetTop = getChildAt(position - firstPos).getTop(); + smoothScrollBy(targetTop - offset, SCROLL_DURATION); + return; + } + + mScrollDuration = SCROLL_DURATION / viewTravelCount; + post(this); + } + void stop() { removeCallbacks(this); } - + public void run() { final int listHeight = getHeight(); final int firstPos = mFirstPosition; @@ -2769,6 +2798,33 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te break; } + case MOVE_OFFSET: { + if (firstPos == mLastSeenPos) { + // No new views, let things keep going. + post(this); + } + + final int position = mTargetPos; + final int lastPos = firstPos + getChildCount() - 1; + + if (position < firstPos) { + final View firstView = getChildAt(0); + final int firstViewPixelsShowing = firstView.getHeight() + firstView.getTop(); + smoothScrollBy(-firstViewPixelsShowing, mScrollDuration); + post(this); + } else if (position > lastPos) { + final View lastView = getChildAt(getChildCount() - 1); + final int lastViewPixelsShowing = lastView.getBottom() - lastView.getHeight(); + smoothScrollBy(lastViewPixelsShowing, mScrollDuration); + post(this); + } else { + // On-screen, just scroll. + final int targetTop = getChildAt(position - firstPos).getTop(); + smoothScrollBy(targetTop - mOffsetFromTop, mScrollDuration); + } + break; + } + default: break; } @@ -2788,6 +2844,24 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } /** + * Smoothly scroll to the specified adapter position. The view will scroll + * such that the indicated position is displayed <code>offset</code> pixels from + * the top edge of the view. If this is impossible, (e.g. the offset would scroll + * the first or last item beyond the boundaries of the list) it will get as close + * as possible. + * + * @param position Position to scroll to + * @param offset Desired distance in pixels of <code>position</code> from the top + * of the view when scrolling is finished + */ + public void smoothScrollToPositionFromTop(int position, int offset) { + if (mPositionScroller == null) { + mPositionScroller = new PositionScroller(); + } + mPositionScroller.startWithOffset(position, offset); + } + + /** * Smoothly scroll to the specified adapter position. The view will * scroll such that the indicated position is displayed, but it will * stop early if scrolling further would scroll boundPosition out of |