summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.xml15
-rw-r--r--core/java/android/widget/AbsListView.java78
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