Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.widget;
     18 
     19 import java.util.ArrayList;
     20 
     21 /**
     22  * ExpandableListPosition can refer to either a group's position or a child's
     23  * position. Referring to a child's position requires both a group position (the
     24  * group containing the child) and a child position (the child's position within
     25  * that group). To create objects, use {@link #obtainChildPosition(int, int)} or
     26  * {@link #obtainGroupPosition(int)}.
     27  */
     28 class ExpandableListPosition {
     29 
     30     private static final int MAX_POOL_SIZE = 5;
     31     private static ArrayList<ExpandableListPosition> sPool =
     32         new ArrayList<ExpandableListPosition>(MAX_POOL_SIZE);
     33 
     34     /**
     35      * This data type represents a child position
     36      */
     37     public final static int CHILD = 1;
     38 
     39     /**
     40      * This data type represents a group position
     41      */
     42     public final static int GROUP = 2;
     43 
     44     /**
     45      * The position of either the group being referred to, or the parent
     46      * group of the child being referred to
     47      */
     48     public int groupPos;
     49 
     50     /**
     51      * The position of the child within its parent group
     52      */
     53     public int childPos;
     54 
     55     /**
     56      * The position of the item in the flat list (optional, used internally when
     57      * the corresponding flat list position for the group or child is known)
     58      */
     59     int flatListPos;
     60 
     61     /**
     62      * What type of position this ExpandableListPosition represents
     63      */
     64     public int type;
     65 
     66     private void resetState() {
     67         groupPos = 0;
     68         childPos = 0;
     69         flatListPos = 0;
     70         type = 0;
     71     }
     72 
     73     private ExpandableListPosition() {
     74     }
     75 
     76     long getPackedPosition() {
     77         if (type == CHILD) return ExpandableListView.getPackedPositionForChild(groupPos, childPos);
     78         else return ExpandableListView.getPackedPositionForGroup(groupPos);
     79     }
     80 
     81     static ExpandableListPosition obtainGroupPosition(int groupPosition) {
     82         return obtain(GROUP, groupPosition, 0, 0);
     83     }
     84 
     85     static ExpandableListPosition obtainChildPosition(int groupPosition, int childPosition) {
     86         return obtain(CHILD, groupPosition, childPosition, 0);
     87     }
     88 
     89     static ExpandableListPosition obtainPosition(long packedPosition) {
     90         if (packedPosition == ExpandableListView.PACKED_POSITION_VALUE_NULL) {
     91             return null;
     92         }
     93 
     94         ExpandableListPosition elp = getRecycledOrCreate();
     95         elp.groupPos = ExpandableListView.getPackedPositionGroup(packedPosition);
     96         if (ExpandableListView.getPackedPositionType(packedPosition) ==
     97                 ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
     98             elp.type = CHILD;
     99             elp.childPos = ExpandableListView.getPackedPositionChild(packedPosition);
    100         } else {
    101             elp.type = GROUP;
    102         }
    103         return elp;
    104     }
    105 
    106     static ExpandableListPosition obtain(int type, int groupPos, int childPos, int flatListPos) {
    107         ExpandableListPosition elp = getRecycledOrCreate();
    108         elp.type = type;
    109         elp.groupPos = groupPos;
    110         elp.childPos = childPos;
    111         elp.flatListPos = flatListPos;
    112         return elp;
    113     }
    114 
    115     private static ExpandableListPosition getRecycledOrCreate() {
    116         ExpandableListPosition elp;
    117         synchronized (sPool) {
    118             if (sPool.size() > 0) {
    119                 elp = sPool.remove(0);
    120             } else {
    121                 return new ExpandableListPosition();
    122             }
    123         }
    124         elp.resetState();
    125         return elp;
    126     }
    127 
    128     /**
    129      * Do not call this unless you obtained this via ExpandableListPosition.obtain().
    130      * PositionMetadata will handle recycling its own children.
    131      */
    132     public void recycle() {
    133         synchronized (sPool) {
    134             if (sPool.size() < MAX_POOL_SIZE) {
    135                 sPool.add(this);
    136             }
    137         }
    138     }
    139 }
    140