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