Cherry pick IndexListAdapter fix into i-dev
ag/1813291 already fixes the bug. Cherry pick it back to i-dev.
Test: Manually verified position of pinned header following
bug repro steps.
Also verified correct behavior when rotating while the header is
fading away.
Bug: 36638590
Change-Id: Ic3c3e97cb6768e96a10c9a36113716090720357a
diff --git a/src/com/android/contacts/list/IndexerListAdapter.java b/src/com/android/contacts/list/IndexerListAdapter.java
index b4ac2b4..969e6a2 100644
--- a/src/com/android/contacts/list/IndexerListAdapter.java
+++ b/src/com/android/contacts/list/IndexerListAdapter.java
@@ -173,7 +173,7 @@
if (section == -1) {
listView.setHeaderInvisible(index, false);
} else {
- View topChild = listView.getChildAt(listPosition);
+ View topChild = getViewAtVisiblePosition(listView, listPosition);
if (topChild != null) {
// Match the pinned header's height to the height of the list item.
mHeader.setMinimumHeight(topChild.getMeasuredHeight());
@@ -195,6 +195,26 @@
}
/**
+ * Returns the view used for the specified list position assuming it is visible or null if
+ * it isn't.
+ *
+ * <p>This makes some assumptions about the implementation of ListView (child views are the
+ * item views and are ordered in the same way as the adapter items they are displaying)
+ * but they are probably safe given that the API is stable.</p>
+ */
+ private View getViewAtVisiblePosition(ListView list, int position) {
+ final int firstVisiblePosition = list.getFirstVisiblePosition();
+ final int childCount = list.getChildCount();
+ final int index = position - firstVisiblePosition;
+ if (index >= 0 && index < childCount) {
+ // Position is on-screen, use existing view.
+ return list.getChildAt(index);
+ } else {
+ return null;
+ }
+ }
+
+ /**
* Computes the item's placement within its section and populates the {@code placement}
* object accordingly. Please note that the returned object is volatile and should be
* copied if the result needs to be used later.