Skip to content

Commit 0061e16

Browse files
committed
Don't allow apps to request scrolls to out-of-bounds positions
An app was requesting smooth scrolling to a view position beyond the number of items in the list. This caused our setup logic to execute on every frame, waiting for the target view to be added. This fix clamps the requested target position to the number of items actually in the list. Issue #6572175 Messaging: Sometimes conversation doesn't scroll when focus is brought to the compose field Change-Id: I23707aeb213e67af4297713a03c2f5b446c8e2b6
1 parent 059537e commit 0061e16

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

core/java/android/widget/AbsListView.java

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4289,14 +4289,15 @@ void start(final int position) {
42894289
final int lastPos = firstPos + childCount - 1;
42904290

42914291
int viewTravelCount;
4292-
if (position < firstPos) {
4293-
viewTravelCount = firstPos - position + 1;
4292+
int clampedPosition = Math.max(0, Math.min(getCount() - 1, position));
4293+
if (clampedPosition < firstPos) {
4294+
viewTravelCount = firstPos - clampedPosition + 1;
42944295
mMode = MOVE_UP_POS;
4295-
} else if (position > lastPos) {
4296-
viewTravelCount = position - lastPos + 1;
4296+
} else if (clampedPosition > lastPos) {
4297+
viewTravelCount = clampedPosition - lastPos + 1;
42974298
mMode = MOVE_DOWN_POS;
42984299
} else {
4299-
scrollToVisible(position, INVALID_POSITION, SCROLL_DURATION);
4300+
scrollToVisible(clampedPosition, INVALID_POSITION, SCROLL_DURATION);
43004301
return;
43014302
}
43024303

@@ -4305,7 +4306,7 @@ void start(final int position) {
43054306
} else {
43064307
mScrollDuration = SCROLL_DURATION;
43074308
}
4308-
mTargetPos = position;
4309+
mTargetPos = clampedPosition;
43094310
mBoundPos = INVALID_POSITION;
43104311
mLastSeenPos = INVALID_POSITION;
43114312

@@ -4340,14 +4341,15 @@ void start(final int position, final int boundPosition) {
43404341
final int lastPos = firstPos + childCount - 1;
43414342

43424343
int viewTravelCount;
4343-
if (position < firstPos) {
4344+
int clampedPosition = Math.max(0, Math.min(getCount() - 1, position));
4345+
if (clampedPosition < firstPos) {
43444346
final int boundPosFromLast = lastPos - boundPosition;
43454347
if (boundPosFromLast < 1) {
43464348
// Moving would shift our bound position off the screen. Abort.
43474349
return;
43484350
}
43494351

4350-
final int posTravel = firstPos - position + 1;
4352+
final int posTravel = firstPos - clampedPosition + 1;
43514353
final int boundTravel = boundPosFromLast - 1;
43524354
if (boundTravel < posTravel) {
43534355
viewTravelCount = boundTravel;
@@ -4356,14 +4358,14 @@ void start(final int position, final int boundPosition) {
43564358
viewTravelCount = posTravel;
43574359
mMode = MOVE_UP_POS;
43584360
}
4359-
} else if (position > lastPos) {
4361+
} else if (clampedPosition > lastPos) {
43604362
final int boundPosFromFirst = boundPosition - firstPos;
43614363
if (boundPosFromFirst < 1) {
43624364
// Moving would shift our bound position off the screen. Abort.
43634365
return;
43644366
}
43654367

4366-
final int posTravel = position - lastPos + 1;
4368+
final int posTravel = clampedPosition - lastPos + 1;
43674369
final int boundTravel = boundPosFromFirst - 1;
43684370
if (boundTravel < posTravel) {
43694371
viewTravelCount = boundTravel;
@@ -4373,7 +4375,7 @@ void start(final int position, final int boundPosition) {
43734375
mMode = MOVE_DOWN_POS;
43744376
}
43754377
} else {
4376-
scrollToVisible(position, boundPosition, SCROLL_DURATION);
4378+
scrollToVisible(clampedPosition, boundPosition, SCROLL_DURATION);
43774379
return;
43784380
}
43794381

@@ -4382,7 +4384,7 @@ void start(final int position, final int boundPosition) {
43824384
} else {
43834385
mScrollDuration = SCROLL_DURATION;
43844386
}
4385-
mTargetPos = position;
4387+
mTargetPos = clampedPosition;
43864388
mBoundPos = boundPosition;
43874389
mLastSeenPos = INVALID_POSITION;
43884390

@@ -4415,7 +4417,7 @@ void startWithOffset(final int position, int offset, final int duration) {
44154417

44164418
offset += getPaddingTop();
44174419

4418-
mTargetPos = position;
4420+
mTargetPos = Math.max(0, Math.min(getCount() - 1, position));
44194421
mOffsetFromTop = offset;
44204422
mBoundPos = INVALID_POSITION;
44214423
mLastSeenPos = INVALID_POSITION;
@@ -4425,13 +4427,13 @@ void startWithOffset(final int position, int offset, final int duration) {
44254427
final int lastPos = firstPos + childCount - 1;
44264428

44274429
int viewTravelCount;
4428-
if (position < firstPos) {
4429-
viewTravelCount = firstPos - position;
4430-
} else if (position > lastPos) {
4431-
viewTravelCount = position - lastPos;
4430+
if (mTargetPos < firstPos) {
4431+
viewTravelCount = firstPos - mTargetPos;
4432+
} else if (mTargetPos > lastPos) {
4433+
viewTravelCount = mTargetPos - lastPos;
44324434
} else {
44334435
// On-screen, just scroll.
4434-
final int targetTop = getChildAt(position - firstPos).getTop();
4436+
final int targetTop = getChildAt(mTargetPos - firstPos).getTop();
44354437
smoothScrollBy(targetTop - offset, duration, true);
44364438
return;
44374439
}

0 commit comments

Comments
 (0)