OSDN Git Service

More ExpandableListView fixes to take headers into account.
authorGilles Debunne <debunne@google.com>
Wed, 3 Mar 2010 23:55:13 +0000 (15:55 -0800)
committerGilles Debunne <debunne@google.com>
Wed, 3 Mar 2010 23:55:13 +0000 (15:55 -0800)
All direct calls to mConnector in ExpandableListView should convert group/child flat positions
to/from absolute flat positions (that take header count into account).
Two conversion methods were added to do that.

core/java/android/widget/ExpandableListConnector.java
core/java/android/widget/ExpandableListView.java

index 9c43e9b..01d3a4a 100644 (file)
@@ -67,7 +67,7 @@ class ExpandableListConnector extends BaseAdapter implements Filterable {
     private int mMaxExpGroupCount = Integer.MAX_VALUE;
 
     /** Change observer used to have ExpandableListAdapter changes pushed to us */
-    private DataSetObserver mDataSetObserver = new MyDataSetObserver();
+    private final DataSetObserver mDataSetObserver = new MyDataSetObserver();
 
     /**
      * Constructs the connector
@@ -849,7 +849,7 @@ class ExpandableListConnector extends BaseAdapter implements Filterable {
      * position to either a) group position for groups, or b) child position for
      * children
      */
-    static class GroupMetadata implements Parcelable, Comparable {
+    static class GroupMetadata implements Parcelable, Comparable<GroupMetadata> {
         final static int REFRESH = -1;
         
         /** This group's flat list position */
@@ -885,12 +885,12 @@ class ExpandableListConnector extends BaseAdapter implements Filterable {
             return gm;
         }
         
-        public int compareTo(Object another) {
-            if (another == null || !(another instanceof GroupMetadata)) {
-                throw new ClassCastException();
+        public int compareTo(GroupMetadata another) {
+            if (another == null) {
+                throw new IllegalArgumentException();
             }
             
-            return gPos - ((GroupMetadata) another).gPos;
+            return gPos - another.gPos;
         }
 
         public int describeContents() {
index 9cc8bd5..8bd797b 100644 (file)
@@ -389,7 +389,8 @@ public class ExpandableListView extends ListView {
         // Only proceed as possible child if the divider isn't above all items (if it is above
         // all items, then the item below it has to be a group)
         if (flatListPosition >= 0) {
-            PositionMetadata pos = mConnector.getUnflattenedPos(flatListPosition);
+            final int adjustedPosition = getFlatPositionForConnector(flatListPosition);
+            PositionMetadata pos = mConnector.getUnflattenedPos(adjustedPosition);
             // If this item is a child, or it is a non-empty group that is expanded
             if ((pos.position.type == ExpandableListPosition.CHILD) || (pos.isExpanded() &&
                     pos.groupMetadata.lastChildFlPos != pos.groupMetadata.flPos)) {
@@ -482,11 +483,37 @@ public class ExpandableListView extends ListView {
         return mAdapter;
     }
     
+    /**
+     * @param position An absolute (including header and footer) flat list position.
+     * @return true if the position corresponds to a header or a footer item.
+     */
     private boolean isHeaderOrFooterPosition(int position) {
         final int footerViewsStart = mItemCount - getFooterViewsCount();
         return (position < getHeaderViewsCount() || position >= footerViewsStart);
     }
 
+    /**
+     * Converts an absolute item flat position into a group/child flat position, shifting according
+     * to the number of header items.
+     * 
+     * @param flatListPosition The absolute flat position
+     * @return A group/child flat position as expected by the connector.
+     */
+    private int getFlatPositionForConnector(int flatListPosition) {
+        return flatListPosition - getHeaderViewsCount();
+    }
+
+    /**
+     * Converts a group/child flat position into an absolute flat position, that takes into account
+     * the possible headers.
+     * 
+     * @param flatListPosition The child/group flat position
+     * @return An absolute flat position.
+     */
+    private int getAbsoluteFlatPosition(int flatListPosition) {
+        return flatListPosition + getHeaderViewsCount();
+    }
+
     @Override
     public boolean performItemClick(View v, int position, long id) {
         // Ignore clicks in header/footers
@@ -496,8 +523,8 @@ public class ExpandableListView extends ListView {
         }
         
         // Internally handle the item click
-        final int headerViewsCount = getHeaderViewsCount();
-        return handleItemClick(v, position - headerViewsCount, id);
+        final int adjustedPosition = getFlatPositionForConnector(position);
+        return handleItemClick(v, adjustedPosition, id);
     }
     
     /**
@@ -711,8 +738,8 @@ public class ExpandableListView extends ListView {
             return PACKED_POSITION_VALUE_NULL;
         }
 
-        final int shiftedPosition = flatListPosition - getHeaderViewsCount();
-        PositionMetadata pm = mConnector.getUnflattenedPos(shiftedPosition);
+        final int adjustedPosition = getFlatPositionForConnector(flatListPosition);
+        PositionMetadata pm = mConnector.getUnflattenedPos(adjustedPosition);
         long packedPos = pm.position.getPackedPosition();
         pm.recycle();
         return packedPos;
@@ -732,9 +759,9 @@ public class ExpandableListView extends ListView {
     public int getFlatListPosition(long packedPosition) {
         PositionMetadata pm = mConnector.getFlattenedPos(ExpandableListPosition
                 .obtainPosition(packedPosition));
-        int retValue = pm.position.flatListPos;
+        final int flatListPosition = pm.position.flatListPos;
         pm.recycle();
-        return retValue + getHeaderViewsCount();
+        return getAbsoluteFlatPosition(flatListPosition);
     }
 
     /**
@@ -783,7 +810,8 @@ public class ExpandableListView extends ListView {
                 .obtainGroupPosition(groupPosition);
         PositionMetadata pm = mConnector.getFlattenedPos(elGroupPos);
         elGroupPos.recycle();
-        super.setSelection(pm.position.flatListPos);
+        final int absoluteFlatPosition = getAbsoluteFlatPosition(pm.position.flatListPos);
+        super.setSelection(absoluteFlatPosition);
         pm.recycle();
     }
     
@@ -819,7 +847,8 @@ public class ExpandableListView extends ListView {
             }
         }
         
-        super.setSelection(flatChildPos.position.flatListPos);
+        int absoluteFlatPosition = getAbsoluteFlatPosition(flatChildPos.position.flatListPos);
+        super.setSelection(absoluteFlatPosition);
         
         elChildPos.recycle();
         flatChildPos.recycle();
@@ -937,7 +966,7 @@ public class ExpandableListView extends ListView {
             return new AdapterContextMenuInfo(view, flatListPosition, id);
         }
 
-        final int adjustedPosition = flatListPosition - getHeaderViewsCount();
+        final int adjustedPosition = getFlatPositionForConnector(flatListPosition);
         PositionMetadata pm = mConnector.getUnflattenedPos(adjustedPosition);
         ExpandableListPosition pos = pm.position;
         pm.recycle();