Home | History | Annotate | Download | only in fragments
      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 com.android.loaderapp.fragments;
     18 
     19 import android.content.Context;
     20 import android.net.Uri;
     21 import android.os.Parcel;
     22 import android.view.LayoutInflater;
     23 import android.view.View;
     24 import android.view.ViewGroup;
     25 import android.widget.BaseAdapter;
     26 
     27 import java.util.ArrayList;
     28 
     29 public abstract class ContactEntryAdapter<E extends ContactEntryAdapter.Entry>
     30         extends BaseAdapter {
     31 
     32     protected ArrayList<ArrayList<E>> mSections;
     33     protected LayoutInflater mInflater;
     34     protected Context mContext;
     35     protected boolean mSeparators;
     36 
     37     /**
     38      * Base class for adapter entries.
     39      */
     40     public static class Entry {
     41         public int type = -1;
     42         public String label;
     43         public String data;
     44         public Uri uri;
     45         public long id = 0;
     46         public long contactId;
     47         public int maxLines = 1;
     48         public String mimetype;
     49 
     50         /**
     51          * Helper for making subclasses parcelable.
     52          */
     53         protected void writeToParcel(Parcel p) {
     54             p.writeInt(type);
     55             p.writeString(label);
     56             p.writeString(data);
     57             p.writeParcelable(uri, 0);
     58             p.writeLong(id);
     59             p.writeInt(maxLines);
     60             p.writeString(mimetype);
     61         }
     62 
     63         /**
     64          * Helper for making subclasses parcelable.
     65          */
     66         protected void readFromParcel(Parcel p) {
     67             final ClassLoader loader = getClass().getClassLoader();
     68             type = p.readInt();
     69             label = p.readString();
     70             data = p.readString();
     71             uri = p.readParcelable(loader);
     72             id = p.readLong();
     73             maxLines = p.readInt();
     74             mimetype = p.readString();
     75         }
     76     }
     77 
     78     ContactEntryAdapter(Context context, ArrayList<ArrayList<E>> sections, boolean separators) {
     79         mContext = context;
     80         mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     81         mSections = sections;
     82         mSeparators = separators;
     83     }
     84 
     85     /**
     86      * Resets the section data.
     87      *
     88      * @param sections the section data
     89      */
     90     public final void setSections(ArrayList<ArrayList<E>> sections, boolean separators) {
     91         mSections = sections;
     92         mSeparators = separators;
     93         notifyDataSetChanged();
     94     }
     95 
     96     /**
     97      * Resets the section data and returns the position of the given entry.
     98      *
     99      * @param sections the section data
    100      * @param entry the entry to return the position for
    101      * @return the position of entry, or -1 if it isn't found
    102      */
    103     public final int setSections(ArrayList<ArrayList<E>> sections, E entry) {
    104         mSections = sections;
    105         notifyDataSetChanged();
    106 
    107         int numSections = mSections.size();
    108         int position = 0;
    109         for (int i = 0; i < numSections; i++) {
    110             ArrayList<E> section = mSections.get(i);
    111             int sectionSize = section.size();
    112             for (int j = 0; j < sectionSize; j++) {
    113                 E e = section.get(j);
    114                 if (e.equals(entry)) {
    115                     position += j;
    116                     return position;
    117                 }
    118             }
    119             position += sectionSize;
    120         }
    121         return -1;
    122     }
    123 
    124     /**
    125      * @see android.widget.ListAdapter#getCount()
    126      */
    127     public final int getCount() {
    128         return countEntries(mSections, mSeparators);
    129     }
    130 
    131     /**
    132      * @see android.widget.ListAdapter#hasSeparators()
    133      */
    134     @Override
    135     public final boolean areAllItemsEnabled() {
    136         return mSeparators == false;
    137     }
    138 
    139     /**
    140      * @see android.widget.ListAdapter#isSeparator(int)
    141      */
    142     @Override
    143     public final boolean isEnabled(int position) {
    144         if (!mSeparators) {
    145             return true;
    146         }
    147 
    148         int numSections = mSections.size();
    149         for (int i = 0; i < numSections; i++) {
    150             ArrayList<E> section = mSections.get(i);
    151             int sectionSize = section.size();
    152             if (sectionSize == 1) {
    153                 // The section only contains a separator and nothing else, skip it
    154                 continue;
    155             }
    156             if (position == 0) {
    157                 // The first item in a section is always the separator
    158                 return false;
    159             }
    160             position -= sectionSize;
    161         }
    162         return true;
    163     }
    164 
    165     /**
    166      * @see android.widget.ListAdapter#getItem(int)
    167      */
    168     public final Object getItem(int position) {
    169         return getEntry(mSections, position, mSeparators);
    170     }
    171 
    172     /**
    173      * Get the entry for the given position.
    174      *
    175      * @param sections the list of sections
    176      * @param position the position for the desired entry
    177      * @return the ContactEntry for the given position
    178      */
    179     public final static <T extends Entry> T getEntry(ArrayList<ArrayList<T>> sections,
    180             int position, boolean separators) {
    181         int numSections = sections.size();
    182         for (int i = 0; i < numSections; i++) {
    183             ArrayList<T> section = sections.get(i);
    184             int sectionSize = section.size();
    185             if (separators && sectionSize == 1) {
    186                 // The section only contains a separator and nothing else, skip it
    187                 continue;
    188             }
    189             if (position < section.size()) {
    190                 return section.get(position);
    191             }
    192             position -= section.size();
    193         }
    194         return null;
    195     }
    196 
    197     /**
    198      * Get the count of entries in all sections
    199      *
    200      * @param sections the list of sections
    201      * @return the count of entries in all sections
    202      */
    203     public static <T extends Entry> int countEntries(ArrayList<ArrayList<T>> sections,
    204             boolean separators) {
    205         int count = 0;
    206         int numSections = sections.size();
    207         for (int i = 0; i < numSections; i++) {
    208             ArrayList<T> section = sections.get(i);
    209             int sectionSize = section.size();
    210             if (separators && sectionSize == 1) {
    211                 // The section only contains a separator and nothing else, skip it
    212                 continue;
    213             }
    214             count += sections.get(i).size();
    215         }
    216         return count;
    217     }
    218 
    219     /**
    220      * @see android.widget.ListAdapter#getItemId(int)
    221      */
    222     public final long getItemId(int position) {
    223         Entry entry = getEntry(mSections, position, mSeparators);
    224         if (entry != null) {
    225             return entry.id;
    226         } else {
    227             return -1;
    228         }
    229     }
    230 
    231     /**
    232      * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
    233      */
    234     public View getView(int position, View convertView, ViewGroup parent) {
    235         View v;
    236         if (convertView == null) {
    237             v = newView(position, parent);
    238         } else {
    239             v = convertView;
    240         }
    241         bindView(v, getEntry(mSections, position, mSeparators));
    242         return v;
    243     }
    244 
    245     /**
    246      * Create a new view for an entry.
    247      *
    248      * @parent the parent ViewGroup
    249      * @return the newly created view
    250      */
    251     protected abstract View newView(int position, ViewGroup parent);
    252 
    253     /**
    254      * Binds the data from an entry to a view.
    255      *
    256      * @param view the view to display the entry in
    257      * @param entry the data to bind
    258      */
    259     protected abstract void bindView(View view, E entry);
    260 }
    261