OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / packages / apps / Contacts / src / com / android / contacts / ContactsSectionIndexer.java
1 /*
2  * Copyright (C) 2010 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 com.android.contacts;
18
19 import android.widget.SectionIndexer;
20
21 import java.util.Arrays;
22
23 /**
24  * A section indexer that is configured with precomputed section titles and
25  * their respective counts.
26  */
27 public class ContactsSectionIndexer implements SectionIndexer {
28
29     private final String[] mSections;
30     private final int[] mPositions;
31     private final int mCount;
32
33     /**
34      * Constructor.
35      *
36      * @param sections a non-null array
37      * @param counts a non-null array of the same size as <code>sections</code>
38      */
39     public ContactsSectionIndexer(String[] sections, int[] counts) {
40         if (sections == null || counts == null) {
41             throw new NullPointerException();
42         }
43
44         if (sections.length != counts.length) {
45             throw new IllegalArgumentException(
46                     "The sections and counts arrays must have the same length");
47         }
48
49         // TODO process sections/counts based on current locale and/or specific section titles
50
51         this.mSections = sections;
52         mPositions = new int[counts.length];
53         int position = 0;
54         for (int i = 0; i < counts.length; i++) {
55             if (mSections[i] == null) {
56                 mSections[i] = " ";
57             } else {
58                 mSections[i] = mSections[i].trim();
59             }
60
61             mPositions[i] = position;
62             position += counts[i];
63         }
64         mCount = position;
65     }
66
67     public Object[] getSections() {
68         return mSections;
69     }
70
71     public int getPositionForSection(int section) {
72         if (section < 0 || section >= mSections.length) {
73             return -1;
74         }
75
76         return mPositions[section];
77     }
78
79     public int getSectionForPosition(int position) {
80         if (position < 0 || position >= mCount) {
81             return -1;
82         }
83
84         int index = Arrays.binarySearch(mPositions, position);
85
86         /*
87          * Consider this example: section positions are 0, 3, 5; the supplied
88          * position is 4. The section corresponding to position 4 starts at
89          * position 3, so the expected return value is 1. Binary search will not
90          * find 4 in the array and thus will return -insertPosition-1, i.e. -3.
91          * To get from that number to the expected value of 1 we need to negate
92          * and subtract 2.
93          */
94         return index >= 0 ? index : -index - 2;
95     }
96 }