From db68fac12daa2cf4a7568308995e218aed92728a Mon Sep 17 00:00:00 2001 From: Jaewan Kim Date: Mon, 4 Feb 2013 01:12:28 +0900 Subject: Fix ListView is not scrolled properly with arrows According to ListView's layoutChildren logic, it detaches all children and rebuilds its children based on visible area which might omit invisible elements in the adapter. In this case, arrowScroll methods only tries to find next scroll candidates from its children so user is unable to scroll more with D-pad. This fixes the issue by look forward next child among the adapter as well as children. Bug: 7346868 Change-Id: I01ab19ad899b5bcb5ab420ddf08c9ffd136933d1 --- core/java/android/widget/ListView.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 69e3177e74b1..4436fbbf2a9e 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -2429,7 +2429,9 @@ public class ListView extends AbsListView { View selectedView = getSelectedView(); int selectedPos = mSelectedPosition; - int nextSelectedPosition = lookForSelectablePositionOnScreen(direction); + int nextSelectedPosition = (direction == View.FOCUS_DOWN) ? + lookForSelectablePosition(selectedPos + 1, true) : + lookForSelectablePosition(selectedPos - 1, false); int amountToScroll = amountToScroll(direction, nextSelectedPosition); // if we are moving focus, we may OVERRIDE the default behavior @@ -2641,14 +2643,18 @@ public class ListView extends AbsListView { final int listBottom = getHeight() - mListPadding.bottom; final int listTop = mListPadding.top; - final int numChildren = getChildCount(); + int numChildren = getChildCount(); if (direction == View.FOCUS_DOWN) { int indexToMakeVisible = numChildren - 1; if (nextSelectedPosition != INVALID_POSITION) { indexToMakeVisible = nextSelectedPosition - mFirstPosition; } - + while (numChildren <= indexToMakeVisible) { + // Child to view is not attached yet. + addViewBelow(getChildAt(numChildren - 1), mFirstPosition + numChildren - 1); + numChildren++; + } final int positionToMakeVisible = mFirstPosition + indexToMakeVisible; final View viewToMakeVisible = getChildAt(indexToMakeVisible); @@ -2682,6 +2688,12 @@ public class ListView extends AbsListView { if (nextSelectedPosition != INVALID_POSITION) { indexToMakeVisible = nextSelectedPosition - mFirstPosition; } + while (indexToMakeVisible < 0) { + // Child to view is not attached yet. + addViewAbove(getChildAt(0), mFirstPosition); + mFirstPosition--; + indexToMakeVisible = nextSelectedPosition - mFirstPosition; + } final int positionToMakeVisible = mFirstPosition + indexToMakeVisible; final View viewToMakeVisible = getChildAt(indexToMakeVisible); int goalTop = listTop; -- cgit v1.2.3-59-g8ed1b