am 6392a360: Merge "Fix misc. bugs in AbsListView smooth scrolling." into jb-dev
* commit '6392a3609cb6457aec715804e15b51fa498141c6': Fix misc. bugs in AbsListView smooth scrolling.
This commit is contained in:
@@ -3985,7 +3985,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
}
|
}
|
||||||
|
|
||||||
class PositionScroller implements Runnable {
|
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_DOWN_POS = 1;
|
||||||
private static final int MOVE_UP_POS = 2;
|
private static final int MOVE_UP_POS = 2;
|
||||||
@@ -4006,21 +4006,35 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
mExtraScroll = ViewConfiguration.get(mContext).getScaledFadingEdgeLength();
|
mExtraScroll = ViewConfiguration.get(mContext).getScaledFadingEdgeLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
void start(int position) {
|
void start(final int position) {
|
||||||
stop();
|
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 firstPos = mFirstPosition;
|
||||||
final int lastPos = firstPos + getChildCount() - 1;
|
final int lastPos = firstPos + childCount - 1;
|
||||||
|
|
||||||
int viewTravelCount;
|
int viewTravelCount;
|
||||||
if (position <= firstPos) {
|
if (position < firstPos) {
|
||||||
viewTravelCount = firstPos - position + 1;
|
viewTravelCount = firstPos - position + 1;
|
||||||
mMode = MOVE_UP_POS;
|
mMode = MOVE_UP_POS;
|
||||||
} else if (position >= lastPos) {
|
} else if (position > lastPos) {
|
||||||
viewTravelCount = position - lastPos + 1;
|
viewTravelCount = position - lastPos + 1;
|
||||||
mMode = MOVE_DOWN_POS;
|
mMode = MOVE_DOWN_POS;
|
||||||
} else {
|
} else {
|
||||||
// Already on screen, nothing to do
|
scrollToVisible(position, INVALID_POSITION, SCROLL_DURATION);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4036,7 +4050,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
postOnAnimation(this);
|
postOnAnimation(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start(int position, int boundPosition) {
|
void start(final int position, final int boundPosition) {
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
if (boundPosition == INVALID_POSITION) {
|
if (boundPosition == INVALID_POSITION) {
|
||||||
@@ -4044,11 +4058,25 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
return;
|
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 firstPos = mFirstPosition;
|
||||||
final int lastPos = firstPos + getChildCount() - 1;
|
final int lastPos = firstPos + childCount - 1;
|
||||||
|
|
||||||
int viewTravelCount;
|
int viewTravelCount;
|
||||||
if (position <= firstPos) {
|
if (position < firstPos) {
|
||||||
final int boundPosFromLast = lastPos - boundPosition;
|
final int boundPosFromLast = lastPos - boundPosition;
|
||||||
if (boundPosFromLast < 1) {
|
if (boundPosFromLast < 1) {
|
||||||
// Moving would shift our bound position off the screen. Abort.
|
// Moving would shift our bound position off the screen. Abort.
|
||||||
@@ -4064,7 +4092,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
viewTravelCount = posTravel;
|
viewTravelCount = posTravel;
|
||||||
mMode = MOVE_UP_POS;
|
mMode = MOVE_UP_POS;
|
||||||
}
|
}
|
||||||
} else if (position >= lastPos) {
|
} else if (position > lastPos) {
|
||||||
final int boundPosFromFirst = boundPosition - firstPos;
|
final int boundPosFromFirst = boundPosition - firstPos;
|
||||||
if (boundPosFromFirst < 1) {
|
if (boundPosFromFirst < 1) {
|
||||||
// Moving would shift our bound position off the screen. Abort.
|
// Moving would shift our bound position off the screen. Abort.
|
||||||
@@ -4081,7 +4109,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
mMode = MOVE_DOWN_POS;
|
mMode = MOVE_DOWN_POS;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Already on screen, nothing to do
|
scrollToVisible(position, boundPosition, SCROLL_DURATION);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4137,6 +4165,60 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
|||||||
postOnAnimation(this);
|
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() {
|
void stop() {
|
||||||
removeCallbacks(this);
|
removeCallbacks(this);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user