19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.DataSetObserver; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Implementation notes: 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Terminology: 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> flPos - Flat list position, the position used by ListView 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> gPos - Group position, the position of a group among all the groups 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> cPos - Child position, the position of a child among all the children 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in a group 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A {@link BaseAdapter} that provides data/Views in an expandable list (offers 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * features such as collapsing/expanding groups containing children). By 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * itself, this adapter has no data and is a connector to a 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ExpandableListAdapter} which provides the data. 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Internally, this connector translates the flat list position that the 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ListAdapter expects to/from group and child positions that the ExpandableListAdapter 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * expects. 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass ExpandableListConnector extends BaseAdapter implements Filterable { 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The ExpandableListAdapter to fetch the data/Views for this expandable list 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ExpandableListAdapter mExpandableListAdapter; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * List of metadata for the currently expanded groups. The metadata consists 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of data essential for efficiently translating between flat list positions 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and group/child positions. See {@link GroupMetadata}. 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<GroupMetadata> mExpGroupMetadataList; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The number of children from all currently expanded groups */ 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTotalExpChildrenCount; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The maximum number of allowable expanded groups. Defaults to 'no limit' */ 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mMaxExpGroupCount = Integer.MAX_VALUE; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Change observer used to have ExpandableListAdapter changes pushed to us */ 70272f3a9474a70817f8089259da4c2696732dfecbGilles Debunne private final DataSetObserver mDataSetObserver = new MyDataSetObserver(); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Constructs the connector 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ExpandableListConnector(ExpandableListAdapter expandableListAdapter) { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpGroupMetadataList = new ArrayList<GroupMetadata>(); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setExpandableListAdapter(expandableListAdapter); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Point to the {@link ExpandableListAdapter} that will give us data/Views 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param expandableListAdapter the adapter that supplies us with data/Views 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setExpandableListAdapter(ExpandableListAdapter expandableListAdapter) { 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExpandableListAdapter != null) { 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpandableListAdapter.unregisterDataSetObserver(mDataSetObserver); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpandableListAdapter = expandableListAdapter; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project expandableListAdapter.registerDataSetObserver(mDataSetObserver); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Translates a flat list position to either a) group pos if the specified 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * flat list position corresponds to a group, or b) child pos if it 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * corresponds to a child. Performs a binary search on the expanded 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * groups list to find the flat list pos if it is an exp group, otherwise 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * finds where the flat list pos fits in between the exp groups. 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param flPos the flat list position to be translated 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the group position or child position of the specified flat list 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * position encompassed in a {@link PositionMetadata} object 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that contains additional useful info for insertion, etc. 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PositionMetadata getUnflattenedPos(final int flPos) { 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Keep locally since frequent use */ 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<GroupMetadata> egml = mExpGroupMetadataList; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numExpGroups = egml.size(); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Binary search variables */ 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int leftExpGroupIndex = 0; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rightExpGroupIndex = numExpGroups - 1; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int midExpGroupIndex = 0; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GroupMetadata midExpGm; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numExpGroups == 0) { 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * There aren't any expanded groups (hence no visible children 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * either), so flPos must be a group and its group pos will be the 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * same as its flPos 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PositionMetadata.obtain(flPos, ExpandableListPosition.GROUP, flPos, 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project -1, null, 0); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Binary search over the expanded groups to find either the exact 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * expanded group (if we're looking for a group) or the group that 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * contains the child we're looking for. If we are looking for a 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * collapsed group, we will not have a direct match here, but we will 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * find the expanded group just before the group we're searching for (so 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * then we can calculate the group position of the group we're searching 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for). If there isn't an expanded group prior to the group being 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * searched for, then the group being searched for's group position is 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the same as the flat list position (since there are no children before 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it, and all groups before it are collapsed). 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (leftExpGroupIndex <= rightExpGroupIndex) { 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project midExpGroupIndex = 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (rightExpGroupIndex - leftExpGroupIndex) / 2 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + leftExpGroupIndex; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project midExpGm = egml.get(midExpGroupIndex); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (flPos > midExpGm.lastChildFlPos) { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The flat list position is after the current middle group's 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * last child's flat list position, so search right 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leftExpGroupIndex = midExpGroupIndex + 1; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (flPos < midExpGm.flPos) { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The flat list position is before the current middle group's 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * flat list position, so search left 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rightExpGroupIndex = midExpGroupIndex - 1; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (flPos == midExpGm.flPos) { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The flat list position is this middle group's flat list 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * position, so we've found an exact hit 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PositionMetadata.obtain(flPos, ExpandableListPosition.GROUP, 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project midExpGm.gPos, -1, midExpGm, midExpGroupIndex); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (flPos <= midExpGm.lastChildFlPos 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* && flPos > midGm.flPos as deduced from previous 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * conditions */) { 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* The flat list position is a child of the middle group */ 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Subtract the first child's flat list position from the 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified flat list pos to get the child's position within 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the group 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childPos = flPos - (midExpGm.flPos + 1); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PositionMetadata.obtain(flPos, ExpandableListPosition.CHILD, 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project midExpGm.gPos, childPos, midExpGm, midExpGroupIndex); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If we've reached here, it means the flat list position must be a 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * group that is not expanded, since otherwise we would have hit it 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the above search. 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If we are to expand this group later, where would it go in the 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * mExpGroupMetadataList ? 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int insertPosition = 0; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** What is its group position in the list of all groups? */ 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int groupPos = 0; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To figure out exact insertion and prior group positions, we need to 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * determine how we broke out of the binary search. We backtrack 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to see this. 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (leftExpGroupIndex > midExpGroupIndex) { 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This would occur in the first conditional, so the flat list 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * insertion position is after the left group. Also, the 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * leftGroupPos is one more than it should be (since that broke out 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of our binary search), so we decrement it. 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final GroupMetadata leftExpGm = egml.get(leftExpGroupIndex-1); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project insertPosition = leftExpGroupIndex; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sums the number of groups between the prior exp group and this 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one, and then adds it to the prior group's group pos 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupPos = 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (flPos - leftExpGm.lastChildFlPos) + leftExpGm.gPos; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (rightExpGroupIndex < midExpGroupIndex) { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This would occur in the second conditional, so the flat list 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * insertion position is before the right group. Also, the 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rightGroupPos is one less than it should be, so increment it. 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final GroupMetadata rightExpGm = egml.get(++rightExpGroupIndex); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project insertPosition = rightExpGroupIndex; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Subtracts this group's flat list pos from the group after's flat 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * list position to find out how many groups are in between the two 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * groups. Then, subtracts that number from the group after's group 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pos to get this group's pos. 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupPos = rightExpGm.gPos - (rightExpGm.flPos - flPos); 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: clean exit 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("Unknown state"); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PositionMetadata.obtain(flPos, ExpandableListPosition.GROUP, groupPos, -1, 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project null, insertPosition); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Translates either a group pos or a child pos (+ group it belongs to) to a 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * flat list position. If searching for a child and its group is not expanded, this will 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return null since the child isn't being shown in the ListView, and hence it has no 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * position. 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param pos a {@link ExpandableListPosition} representing either a group position 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or child position 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the flat list position encompassed in a {@link PositionMetadata} 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * object that contains additional useful info for insertion, etc., or null. 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PositionMetadata getFlattenedPos(final ExpandableListPosition pos) { 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<GroupMetadata> egml = mExpGroupMetadataList; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numExpGroups = egml.size(); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Binary search variables */ 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int leftExpGroupIndex = 0; 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rightExpGroupIndex = numExpGroups - 1; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int midExpGroupIndex = 0; 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GroupMetadata midExpGm; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numExpGroups == 0) { 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * There aren't any expanded groups, so flPos must be a group and 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * its flPos will be the same as its group pos. The 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * insert position is 0 (since the list is empty). 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PositionMetadata.obtain(pos.groupPos, pos.type, 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos.groupPos, pos.childPos, null, 0); 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Binary search over the expanded groups to find either the exact 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * expanded group (if we're looking for a group) or the group that 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * contains the child we're looking for. 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (leftExpGroupIndex <= rightExpGroupIndex) { 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project midExpGroupIndex = (rightExpGroupIndex - leftExpGroupIndex)/2 + leftExpGroupIndex; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project midExpGm = egml.get(midExpGroupIndex); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos.groupPos > midExpGm.gPos) { 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * It's after the current middle group, so search right 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leftExpGroupIndex = midExpGroupIndex + 1; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (pos.groupPos < midExpGm.gPos) { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * It's before the current middle group, so search left 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rightExpGroupIndex = midExpGroupIndex - 1; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (pos.groupPos == midExpGm.gPos) { 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * It's this middle group, exact hit 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos.type == ExpandableListPosition.GROUP) { 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* If it's a group, give them this matched group's flPos */ 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PositionMetadata.obtain(midExpGm.flPos, pos.type, 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos.groupPos, pos.childPos, midExpGm, midExpGroupIndex); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (pos.type == ExpandableListPosition.CHILD) { 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* If it's a child, calculate the flat list pos */ 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PositionMetadata.obtain(midExpGm.flPos + pos.childPos 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + 1, pos.type, pos.groupPos, pos.childPos, 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project midExpGm, midExpGroupIndex); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If we've reached here, it means there was no match in the expanded 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * groups, so it must be a collapsed group that they're search for 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos.type != ExpandableListPosition.GROUP) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* If it isn't a group, return null */ 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To figure out exact insertion and prior group positions, we need to 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * determine how we broke out of the binary search. We backtrack to see 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this. 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (leftExpGroupIndex > midExpGroupIndex) { 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This would occur in the first conditional, so the flat list 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * insertion position is after the left group. 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The leftGroupPos is one more than it should be (from the binary 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * search loop) so we subtract 1 to get the actual left group. Since 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the insertion point is AFTER the left group, we keep this +1 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * value as the insertion point 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final GroupMetadata leftExpGm = egml.get(leftExpGroupIndex-1); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int flPos = 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leftExpGm.lastChildFlPos 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (pos.groupPos - leftExpGm.gPos); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PositionMetadata.obtain(flPos, pos.type, pos.groupPos, 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos.childPos, null, leftExpGroupIndex); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (rightExpGroupIndex < midExpGroupIndex) { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This would occur in the second conditional, so the flat list 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * insertion position is before the right group. Also, the 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rightGroupPos is one less than it should be (from binary search 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * loop), so we increment to it. 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final GroupMetadata rightExpGm = egml.get(++rightExpGroupIndex); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int flPos = 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rightExpGm.flPos 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project - (rightExpGm.gPos - pos.groupPos); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PositionMetadata.obtain(flPos, pos.type, pos.groupPos, 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos.childPos, null, rightExpGroupIndex); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean areAllItemsEnabled() { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mExpandableListAdapter.areAllItemsEnabled(); 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isEnabled(int flatListPos) { 375820b236adce43567b2effd92e246c34a8a76c9f9John Reck final PositionMetadata metadata = getUnflattenedPos(flatListPos); 376820b236adce43567b2effd92e246c34a8a76c9f9John Reck final ExpandableListPosition pos = metadata.position; 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean retValue; 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos.type == ExpandableListPosition.CHILD) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retValue = mExpandableListAdapter.isChildSelectable(pos.groupPos, pos.childPos); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Groups are always selectable 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retValue = true; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 386820b236adce43567b2effd92e246c34a8a76c9f9John Reck metadata.recycle(); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return retValue; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getCount() { 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Total count for the list view is the number groups plus the 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * number of children from currently expanded groups (a value we keep 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cached in this class) 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mExpandableListAdapter.getGroupCount() + mTotalExpChildrenCount; 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Object getItem(int flatListPos) { 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PositionMetadata posMetadata = getUnflattenedPos(flatListPos); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object retValue; 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (posMetadata.position.type == ExpandableListPosition.GROUP) { 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retValue = mExpandableListAdapter 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .getGroup(posMetadata.position.groupPos); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (posMetadata.position.type == ExpandableListPosition.CHILD) { 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retValue = mExpandableListAdapter.getChild(posMetadata.position.groupPos, 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posMetadata.position.childPos); 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: clean exit 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("Flat list position is of unknown type"); 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posMetadata.recycle(); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return retValue; 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getItemId(int flatListPos) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PositionMetadata posMetadata = getUnflattenedPos(flatListPos); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long groupId = mExpandableListAdapter.getGroupId(posMetadata.position.groupPos); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long retValue; 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (posMetadata.position.type == ExpandableListPosition.GROUP) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retValue = mExpandableListAdapter.getCombinedGroupId(groupId); 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (posMetadata.position.type == ExpandableListPosition.CHILD) { 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long childId = mExpandableListAdapter.getChildId(posMetadata.position.groupPos, 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posMetadata.position.childPos); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retValue = mExpandableListAdapter.getCombinedChildId(groupId, childId); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: clean exit 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("Flat list position is of unknown type"); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posMetadata.recycle(); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return retValue; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View getView(int flatListPos, View convertView, ViewGroup parent) { 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PositionMetadata posMetadata = getUnflattenedPos(flatListPos); 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View retValue; 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (posMetadata.position.type == ExpandableListPosition.GROUP) { 4468340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne retValue = mExpandableListAdapter.getGroupView(posMetadata.position.groupPos, 4478340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne posMetadata.isExpanded(), convertView, parent); 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (posMetadata.position.type == ExpandableListPosition.CHILD) { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean isLastChild = posMetadata.groupMetadata.lastChildFlPos == flatListPos; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retValue = mExpandableListAdapter.getChildView(posMetadata.position.groupPos, 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posMetadata.position.childPos, isLastChild, convertView, parent); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: clean exit 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("Flat list position is of unknown type"); 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posMetadata.recycle(); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return retValue; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getItemViewType(int flatListPos) { 465820b236adce43567b2effd92e246c34a8a76c9f9John Reck final PositionMetadata metadata = getUnflattenedPos(flatListPos); 466820b236adce43567b2effd92e246c34a8a76c9f9John Reck final ExpandableListPosition pos = metadata.position; 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int retValue; 4698340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne if (mExpandableListAdapter instanceof HeterogeneousExpandableList) { 4708340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne HeterogeneousExpandableList adapter = 4718340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne (HeterogeneousExpandableList) mExpandableListAdapter; 4728340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne if (pos.type == ExpandableListPosition.GROUP) { 4738340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne retValue = adapter.getGroupType(pos.groupPos); 4748340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne } else { 4758340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne final int childType = adapter.getChildType(pos.groupPos, pos.childPos); 4768340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne retValue = adapter.getGroupTypeCount() + childType; 4778340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4798340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne if (pos.type == ExpandableListPosition.GROUP) { 4808340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne retValue = 0; 4818340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne } else { 4828340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne retValue = 1; 4838340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne } 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 486820b236adce43567b2effd92e246c34a8a76c9f9John Reck metadata.recycle(); 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return retValue; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getViewTypeCount() { 4938340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne if (mExpandableListAdapter instanceof HeterogeneousExpandableList) { 4948340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne HeterogeneousExpandableList adapter = 4958340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne (HeterogeneousExpandableList) mExpandableListAdapter; 4968340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne return adapter.getGroupTypeCount() + adapter.getChildTypeCount(); 4978340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne } else { 4988340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne return 2; 4998340afe0f66663f032dd999e2d377564df0bb6d5Gilles Debunne } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasStableIds() { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mExpandableListAdapter.hasStableIds(); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Traverses the expanded group metadata list and fills in the flat list 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * positions. 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param forceChildrenCountRefresh Forces refreshing of the children count 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for all expanded groups. 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncGroupPositions Whether to search for the group positions 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * based on the group IDs. This should only be needed when calling 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this from an onChanged callback. 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("unchecked") 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void refreshExpGroupMetadataList(boolean forceChildrenCountRefresh, 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean syncGroupPositions) { 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<GroupMetadata> egml = mExpGroupMetadataList; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int egmlSize = egml.size(); 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int curFlPos = 0; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Update child count as we go through */ 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTotalExpChildrenCount = 0; 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (syncGroupPositions) { 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We need to check whether any groups have moved positions 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean positionsChanged = false; 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = egmlSize - 1; i >= 0; i--) { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GroupMetadata curGm = egml.get(i); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int newGPos = findGroupPosition(curGm.gId, curGm.gPos); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newGPos != curGm.gPos) { 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newGPos == AdapterView.INVALID_POSITION) { 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Doh, just remove it from the list of expanded groups 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project egml.remove(i); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project egmlSize--; 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curGm.gPos = newGPos; 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!positionsChanged) positionsChanged = true; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (positionsChanged) { 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // At least one group changed positions, so re-sort 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Collections.sort(egml); 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int gChildrenCount; 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int lastGPos = 0; 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < egmlSize; i++) { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Store in local variable since we'll access freq */ 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GroupMetadata curGm = egml.get(i); 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Get the number of children, try to refrain from calling 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * another class's method unless we have to (so do a subtraction) 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((curGm.lastChildFlPos == GroupMetadata.REFRESH) || forceChildrenCountRefresh) { 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gChildrenCount = mExpandableListAdapter.getChildrenCount(curGm.gPos); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Num children for this group is its last child's fl pos minus 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the group's fl pos 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gChildrenCount = curGm.lastChildFlPos - curGm.flPos; 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Update */ 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTotalExpChildrenCount += gChildrenCount; 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This skips the collapsed groups and increments the flat list 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * position (for subsequent exp groups) by accounting for the collapsed 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * groups 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlPos += (curGm.gPos - lastGPos); 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastGPos = curGm.gPos; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Update the flat list positions, and the current flat list pos */ 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curGm.flPos = curFlPos; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curFlPos += gChildrenCount; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curGm.lastChildFlPos = curFlPos; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Collapse a group in the grouped list view 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param groupPos position of the group to collapse 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean collapseGroup(int groupPos) { 595820b236adce43567b2effd92e246c34a8a76c9f9John Reck ExpandableListPosition elGroupPos = ExpandableListPosition.obtain( 596820b236adce43567b2effd92e246c34a8a76c9f9John Reck ExpandableListPosition.GROUP, groupPos, -1, -1); 597820b236adce43567b2effd92e246c34a8a76c9f9John Reck PositionMetadata pm = getFlattenedPos(elGroupPos); 598820b236adce43567b2effd92e246c34a8a76c9f9John Reck elGroupPos.recycle(); 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pm == null) return false; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean retValue = collapseGroup(pm); 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pm.recycle(); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return retValue; 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean collapseGroup(PositionMetadata posMetadata) { 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Collapsing requires removal from mExpGroupMetadataList 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If it is null, it must be already collapsed. This group metadata 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * object should have been set from the search that returned the 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * position metadata object. 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (posMetadata.groupMetadata == null) return false; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove the group from the list of expanded groups 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpGroupMetadataList.remove(posMetadata.groupMetadata); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Refresh the metadata 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refreshExpGroupMetadataList(false, false); 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Notify of change 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyDataSetChanged(); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Give the callback 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpandableListAdapter.onGroupCollapsed(posMetadata.groupMetadata.gPos); 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Expand a group in the grouped list view 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param groupPos the group to be expanded 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean expandGroup(int groupPos) { 638820b236adce43567b2effd92e246c34a8a76c9f9John Reck ExpandableListPosition elGroupPos = ExpandableListPosition.obtain( 639820b236adce43567b2effd92e246c34a8a76c9f9John Reck ExpandableListPosition.GROUP, groupPos, -1, -1); 640820b236adce43567b2effd92e246c34a8a76c9f9John Reck PositionMetadata pm = getFlattenedPos(elGroupPos); 641820b236adce43567b2effd92e246c34a8a76c9f9John Reck elGroupPos.recycle(); 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean retValue = expandGroup(pm); 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pm.recycle(); 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return retValue; 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean expandGroup(PositionMetadata posMetadata) { 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Expanding requires insertion into the mExpGroupMetadataList 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (posMetadata.position.groupPos < 0) { 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO clean exit 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("Need group"); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMaxExpGroupCount == 0) return false; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check to see if it's already expanded 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (posMetadata.groupMetadata != null) return false; 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 662192ab903887bbb8e7c7b6da5c581573850e30f46Gilles Debunne /* Restrict number of expanded groups to mMaxExpGroupCount */ 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExpGroupMetadataList.size() >= mMaxExpGroupCount) { 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Collapse a group */ 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: Collapse something not on the screen instead of the first one? 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: Could write overloaded function to take GroupMetadata to collapse 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GroupMetadata collapsedGm = mExpGroupMetadataList.get(0); 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int collapsedIndex = mExpGroupMetadataList.indexOf(collapsedGm); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project collapseGroup(collapsedGm.gPos); 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Decrement index if it is after the group we removed */ 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (posMetadata.groupInsertIndex > collapsedIndex) { 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posMetadata.groupInsertIndex--; 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GroupMetadata expandedGm = GroupMetadata.obtain( 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GroupMetadata.REFRESH, 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GroupMetadata.REFRESH, 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posMetadata.position.groupPos, 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpandableListAdapter.getGroupId(posMetadata.position.groupPos)); 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpGroupMetadataList.add(posMetadata.groupInsertIndex, expandedGm); 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Refresh the metadata 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refreshExpGroupMetadataList(false, false); 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Notify of change 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyDataSetChanged(); 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Give the callback 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpandableListAdapter.onGroupExpanded(expandedGm.gPos); 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Whether the given group is currently expanded. 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param groupPosition The group to check. 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Whether the group is currently expanded. 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isGroupExpanded(int groupPosition) { 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GroupMetadata groupMetadata; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = mExpGroupMetadataList.size() - 1; i >= 0; i--) { 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupMetadata = mExpGroupMetadataList.get(i); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (groupMetadata.gPos == groupPosition) { 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the maximum number of groups that can be expanded at any given time 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setMaxExpGroupCount(int maxExpGroupCount) { 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMaxExpGroupCount = maxExpGroupCount; 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ExpandableListAdapter getAdapter() { 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mExpandableListAdapter; 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Filter getFilter() { 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ExpandableListAdapter adapter = getAdapter(); 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (adapter instanceof Filterable) { 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((Filterable) adapter).getFilter(); 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<GroupMetadata> getExpandedGroupMetadataList() { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mExpGroupMetadataList; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void setExpandedGroupMetadataList(ArrayList<GroupMetadata> expandedGroupMetadataList) { 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((expandedGroupMetadataList == null) || (mExpandableListAdapter == null)) { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure our current data set is big enough for the previously 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // expanded groups, if not, ignore this request 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numGroups = mExpandableListAdapter.getGroupCount(); 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = expandedGroupMetadataList.size() - 1; i >= 0; i--) { 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (expandedGroupMetadataList.get(i).gPos >= numGroups) { 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Doh, for some reason the client doesn't have some of the groups 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpGroupMetadataList = expandedGroupMetadataList; 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refreshExpGroupMetadataList(true, false); 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isEmpty() { 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ExpandableListAdapter adapter = getAdapter(); 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return adapter != null ? adapter.isEmpty() : true; 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Searches the expandable list adapter for a group position matching the 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given group ID. The search starts at the given seed position and then 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * alternates between moving up and moving down until 1) we find the right 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * position, or 2) we run out of time, or 3) we have looked at every 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * position 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Position of the row that matches the given row ID, or 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AdapterView#INVALID_POSITION} if it can't be found 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see AdapterView#findSyncPosition() 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int findGroupPosition(long groupIdToMatch, int seedGroupPosition) { 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = mExpandableListAdapter.getGroupCount(); 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count == 0) { 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AdapterView.INVALID_POSITION; 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If there isn't a selection don't hunt for it 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (groupIdToMatch == AdapterView.INVALID_ROW_ID) { 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AdapterView.INVALID_POSITION; 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Pin seed to reasonable values 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project seedGroupPosition = Math.max(0, seedGroupPosition); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project seedGroupPosition = Math.min(count - 1, seedGroupPosition); 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long endTime = SystemClock.uptimeMillis() + AdapterView.SYNC_MAX_DURATION_MILLIS; 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long rowId; 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // first position scanned so far 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int first = seedGroupPosition; 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // last position scanned so far 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int last = seedGroupPosition; 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // True if we should move down on the next iteration 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean next = false; 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // True when we have looked at the first item in the data 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hitFirst; 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // True when we have looked at the last item in the data 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hitLast; 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get the item ID locally (instead of getItemIdAtPosition), so 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we need the adapter 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ExpandableListAdapter adapter = getAdapter(); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (adapter == null) { 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AdapterView.INVALID_POSITION; 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (SystemClock.uptimeMillis() <= endTime) { 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowId = adapter.getGroupId(seedGroupPosition); 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rowId == groupIdToMatch) { 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Found it! 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return seedGroupPosition; 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hitLast = last == count - 1; 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hitFirst = first == 0; 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hitLast && hitFirst) { 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Looked at everything 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hitFirst || (next && !hitLast)) { 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Either we hit the top, or we are trying to move down 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project last++; 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project seedGroupPosition = last; 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Try going up next time 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project next = false; 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (hitLast || (!next && !hitFirst)) { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Either we hit the bottom, or we are trying to move up 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project first--; 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project seedGroupPosition = first; 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Try going down next time 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project next = true; 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AdapterView.INVALID_POSITION; 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected class MyDataSetObserver extends DataSetObserver { 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onChanged() { 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refreshExpGroupMetadataList(true, true); 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyDataSetChanged(); 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onInvalidated() { 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refreshExpGroupMetadataList(true, true); 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyDataSetInvalidated(); 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Metadata about an expanded group to help convert from a flat list 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * position to either a) group position for groups, or b) child position for 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * children 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 875272f3a9474a70817f8089259da4c2696732dfecbGilles Debunne static class GroupMetadata implements Parcelable, Comparable<GroupMetadata> { 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final static int REFRESH = -1; 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** This group's flat list position */ 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flPos; 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* firstChildFlPos isn't needed since it's (flPos + 1) */ 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This group's last child's flat list position, so basically 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the range of this group in the flat list 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int lastChildFlPos; 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This group's group position 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int gPos; 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This group's id 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long gId; 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GroupMetadata() { 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static GroupMetadata obtain(int flPos, int lastChildFlPos, int gPos, long gId) { 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GroupMetadata gm = new GroupMetadata(); 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gm.flPos = flPos; 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gm.lastChildFlPos = lastChildFlPos; 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gm.gPos = gPos; 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gm.gId = gId; 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return gm; 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 911272f3a9474a70817f8089259da4c2696732dfecbGilles Debunne public int compareTo(GroupMetadata another) { 912272f3a9474a70817f8089259da4c2696732dfecbGilles Debunne if (another == null) { 913272f3a9474a70817f8089259da4c2696732dfecbGilles Debunne throw new IllegalArgumentException(); 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 916272f3a9474a70817f8089259da4c2696732dfecbGilles Debunne return gPos - another.gPos; 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int describeContents() { 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void writeToParcel(Parcel dest, int flags) { 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeInt(flPos); 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeInt(lastChildFlPos); 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeInt(gPos); 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeLong(gId); 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Parcelable.Creator<GroupMetadata> CREATOR = 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new Parcelable.Creator<GroupMetadata>() { 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GroupMetadata createFromParcel(Parcel in) { 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GroupMetadata gm = GroupMetadata.obtain( 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project in.readInt(), 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project in.readInt(), 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project in.readInt(), 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project in.readLong()); 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return gm; 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GroupMetadata[] newArray(int size) { 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new GroupMetadata[size]; 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Data type that contains an expandable list position (can refer to either a group 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or child) and some extra information regarding referred item (such as 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * where to insert into the flat list, etc.) 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public class PositionMetadata { 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_POOL_SIZE = 5; 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static ArrayList<PositionMetadata> sPool = 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new ArrayList<PositionMetadata>(MAX_POOL_SIZE); 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Data type to hold the position and its type (child/group) */ 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ExpandableListPosition position; 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Link back to the expanded GroupMetadata for this group. Useful for 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * removing the group from the list of expanded groups inside the 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * connector when we collapse the group, and also as a check to see if 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the group was expanded or collapsed (this will be null if the group 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is collapsed since we don't keep that group's metadata) 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GroupMetadata groupMetadata; 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For groups that are collapsed, we use this as the index (in 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * mExpGroupMetadataList) to insert this group when we are expanding 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this group. 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int groupInsertIndex; 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void resetState() { 980820b236adce43567b2effd92e246c34a8a76c9f9John Reck if (position != null) { 981820b236adce43567b2effd92e246c34a8a76c9f9John Reck position.recycle(); 982820b236adce43567b2effd92e246c34a8a76c9f9John Reck position = null; 983820b236adce43567b2effd92e246c34a8a76c9f9John Reck } 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupMetadata = null; 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project groupInsertIndex = 0; 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Use {@link #obtain(int, int, int, int, GroupMetadata, int)} 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private PositionMetadata() { 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static PositionMetadata obtain(int flatListPos, int type, int groupPos, 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childPos, GroupMetadata groupMetadata, int groupInsertIndex) { 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PositionMetadata pm = getRecycledOrCreate(); 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pm.position = ExpandableListPosition.obtain(type, groupPos, childPos, flatListPos); 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pm.groupMetadata = groupMetadata; 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pm.groupInsertIndex = groupInsertIndex; 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pm; 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static PositionMetadata getRecycledOrCreate() { 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PositionMetadata pm; 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sPool) { 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sPool.size() > 0) { 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pm = sPool.remove(0); 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new PositionMetadata(); 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pm.resetState(); 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return pm; 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void recycle() { 1017820b236adce43567b2effd92e246c34a8a76c9f9John Reck resetState(); 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sPool) { 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sPool.size() < MAX_POOL_SIZE) { 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sPool.add(this); 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Checks whether the group referred to in this object is expanded, 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or not (at the time this object was created) 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return whether the group at groupPos is expanded or not 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isExpanded() { 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return groupMetadata != null; 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1036