diff --git a/api/current.xml b/api/current.xml
index 192e0bf6329d1..c6df759204538 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -205332,6 +205332,21 @@
+
+
+
+
+
+
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 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 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 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;
}
@@ -2787,6 +2843,24 @@ public abstract class AbsListView extends AdapterView implements Te
mPositionScroller.start(position);
}
+ /**
+ * Smoothly scroll to the specified adapter position. The view will scroll
+ * such that the indicated position is displayed offset 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 position 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