Home | History | Annotate | Download | only in contacts
      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 }
     97