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.