Loading core/java/android/widget/AbsListView.java +93 −11 Original line number Diff line number Diff line Loading @@ -3985,7 +3985,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } class PositionScroller implements Runnable { private static final int SCROLL_DURATION = 400; private static final int SCROLL_DURATION = 200; private static final int MOVE_DOWN_POS = 1; private static final int MOVE_UP_POS = 2; Loading @@ -4006,21 +4006,35 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mExtraScroll = ViewConfiguration.get(mContext).getScaledFadingEdgeLength(); } void start(int position) { void start(final int position) { stop(); final int childCount = getChildCount(); if (childCount == 0) { // Can't scroll without children. if (mDataChanged) { // But we might have something in a minute. post(new Runnable() { @Override public void run() { start(position); } }); } return; } final int firstPos = mFirstPosition; final int lastPos = firstPos + getChildCount() - 1; final int lastPos = firstPos + childCount - 1; int viewTravelCount; if (position <= firstPos) { if (position < firstPos) { viewTravelCount = firstPos - position + 1; mMode = MOVE_UP_POS; } else if (position >= lastPos) { } else if (position > lastPos) { viewTravelCount = position - lastPos + 1; mMode = MOVE_DOWN_POS; } else { // Already on screen, nothing to do scrollToVisible(position, INVALID_POSITION, SCROLL_DURATION); return; } Loading @@ -4036,7 +4050,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te postOnAnimation(this); } void start(int position, int boundPosition) { void start(final int position, final int boundPosition) { stop(); if (boundPosition == INVALID_POSITION) { Loading @@ -4044,11 +4058,25 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return; } final int childCount = getChildCount(); if (childCount == 0) { // Can't scroll without children. if (mDataChanged) { // But we might have something in a minute. post(new Runnable() { @Override public void run() { start(position, boundPosition); } }); } return; } final int firstPos = mFirstPosition; final int lastPos = firstPos + getChildCount() - 1; final int lastPos = firstPos + childCount - 1; int viewTravelCount; if (position <= firstPos) { if (position < firstPos) { final int boundPosFromLast = lastPos - boundPosition; if (boundPosFromLast < 1) { // Moving would shift our bound position off the screen. Abort. Loading @@ -4064,7 +4092,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te viewTravelCount = posTravel; mMode = MOVE_UP_POS; } } else if (position >= lastPos) { } else if (position > lastPos) { final int boundPosFromFirst = boundPosition - firstPos; if (boundPosFromFirst < 1) { // Moving would shift our bound position off the screen. Abort. Loading @@ -4081,7 +4109,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mMode = MOVE_DOWN_POS; } } else { // Already on screen, nothing to do scrollToVisible(position, boundPosition, SCROLL_DURATION); return; } Loading Loading @@ -4137,6 +4165,60 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te postOnAnimation(this); } /** * Scroll such that targetPos is in the visible padded region without scrolling * boundPos out of view. Assumes targetPos is onscreen. */ void scrollToVisible(int targetPos, int boundPos, int duration) { final int firstPos = mFirstPosition; final int childCount = getChildCount(); final int lastPos = firstPos + childCount - 1; final int paddedTop = mListPadding.top; final int paddedBottom = getHeight() - mListPadding.bottom; if (targetPos < firstPos || targetPos > lastPos) { Log.w(TAG, "scrollToVisible called with targetPos " + targetPos + " not visible [" + firstPos + ", " + lastPos + "]"); } if (boundPos < firstPos || boundPos > lastPos) { // boundPos doesn't matter, it's already offscreen. boundPos = INVALID_POSITION; } final View targetChild = getChildAt(targetPos - firstPos); final int targetTop = targetChild.getTop(); final int targetBottom = targetChild.getBottom(); int scrollBy = 0; if (targetBottom > paddedBottom) { scrollBy = targetBottom - paddedBottom; } if (targetTop < paddedTop) { scrollBy = targetTop - paddedTop; } if (scrollBy == 0) { return; } if (boundPos >= 0) { final View boundChild = getChildAt(boundPos - firstPos); final int boundTop = boundChild.getTop(); final int boundBottom = boundChild.getBottom(); final int absScroll = Math.abs(scrollBy); if (scrollBy < 0 && boundBottom + absScroll > paddedBottom) { // Don't scroll the bound view off the bottom of the screen. scrollBy = Math.max(0, boundBottom - paddedBottom); } else if (scrollBy > 0 && boundTop - absScroll < paddedTop) { // Don't scroll the bound view off the top of the screen. scrollBy = Math.min(0, boundTop - paddedTop); } } smoothScrollBy(scrollBy, duration); } void stop() { removeCallbacks(this); } Loading Loading
core/java/android/widget/AbsListView.java +93 −11 Original line number Diff line number Diff line Loading @@ -3985,7 +3985,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } class PositionScroller implements Runnable { private static final int SCROLL_DURATION = 400; private static final int SCROLL_DURATION = 200; private static final int MOVE_DOWN_POS = 1; private static final int MOVE_UP_POS = 2; Loading @@ -4006,21 +4006,35 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mExtraScroll = ViewConfiguration.get(mContext).getScaledFadingEdgeLength(); } void start(int position) { void start(final int position) { stop(); final int childCount = getChildCount(); if (childCount == 0) { // Can't scroll without children. if (mDataChanged) { // But we might have something in a minute. post(new Runnable() { @Override public void run() { start(position); } }); } return; } final int firstPos = mFirstPosition; final int lastPos = firstPos + getChildCount() - 1; final int lastPos = firstPos + childCount - 1; int viewTravelCount; if (position <= firstPos) { if (position < firstPos) { viewTravelCount = firstPos - position + 1; mMode = MOVE_UP_POS; } else if (position >= lastPos) { } else if (position > lastPos) { viewTravelCount = position - lastPos + 1; mMode = MOVE_DOWN_POS; } else { // Already on screen, nothing to do scrollToVisible(position, INVALID_POSITION, SCROLL_DURATION); return; } Loading @@ -4036,7 +4050,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te postOnAnimation(this); } void start(int position, int boundPosition) { void start(final int position, final int boundPosition) { stop(); if (boundPosition == INVALID_POSITION) { Loading @@ -4044,11 +4058,25 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return; } final int childCount = getChildCount(); if (childCount == 0) { // Can't scroll without children. if (mDataChanged) { // But we might have something in a minute. post(new Runnable() { @Override public void run() { start(position, boundPosition); } }); } return; } final int firstPos = mFirstPosition; final int lastPos = firstPos + getChildCount() - 1; final int lastPos = firstPos + childCount - 1; int viewTravelCount; if (position <= firstPos) { if (position < firstPos) { final int boundPosFromLast = lastPos - boundPosition; if (boundPosFromLast < 1) { // Moving would shift our bound position off the screen. Abort. Loading @@ -4064,7 +4092,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te viewTravelCount = posTravel; mMode = MOVE_UP_POS; } } else if (position >= lastPos) { } else if (position > lastPos) { final int boundPosFromFirst = boundPosition - firstPos; if (boundPosFromFirst < 1) { // Moving would shift our bound position off the screen. Abort. Loading @@ -4081,7 +4109,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mMode = MOVE_DOWN_POS; } } else { // Already on screen, nothing to do scrollToVisible(position, boundPosition, SCROLL_DURATION); return; } Loading Loading @@ -4137,6 +4165,60 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te postOnAnimation(this); } /** * Scroll such that targetPos is in the visible padded region without scrolling * boundPos out of view. Assumes targetPos is onscreen. */ void scrollToVisible(int targetPos, int boundPos, int duration) { final int firstPos = mFirstPosition; final int childCount = getChildCount(); final int lastPos = firstPos + childCount - 1; final int paddedTop = mListPadding.top; final int paddedBottom = getHeight() - mListPadding.bottom; if (targetPos < firstPos || targetPos > lastPos) { Log.w(TAG, "scrollToVisible called with targetPos " + targetPos + " not visible [" + firstPos + ", " + lastPos + "]"); } if (boundPos < firstPos || boundPos > lastPos) { // boundPos doesn't matter, it's already offscreen. boundPos = INVALID_POSITION; } final View targetChild = getChildAt(targetPos - firstPos); final int targetTop = targetChild.getTop(); final int targetBottom = targetChild.getBottom(); int scrollBy = 0; if (targetBottom > paddedBottom) { scrollBy = targetBottom - paddedBottom; } if (targetTop < paddedTop) { scrollBy = targetTop - paddedTop; } if (scrollBy == 0) { return; } if (boundPos >= 0) { final View boundChild = getChildAt(boundPos - firstPos); final int boundTop = boundChild.getTop(); final int boundBottom = boundChild.getBottom(); final int absScroll = Math.abs(scrollBy); if (scrollBy < 0 && boundBottom + absScroll > paddedBottom) { // Don't scroll the bound view off the bottom of the screen. scrollBy = Math.max(0, boundBottom - paddedBottom); } else if (scrollBy > 0 && boundTop - absScroll < paddedTop) { // Don't scroll the bound view off the top of the screen. scrollBy = Math.min(0, boundTop - paddedTop); } } smoothScrollBy(scrollBy, duration); } void stop() { removeCallbacks(this); } Loading