blob: 3b28b19080b52ad9de84c3f5f8b9196c89b186e1 [file] [log] [blame]
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -08001/*
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
17package com.android.contacts;
18
19import android.content.Context;
20import android.net.Uri;
21import android.os.Parcel;
Evan Millar66388be2009-05-28 15:41:07 -070022import android.provider.ContactsContract.Aggregates;
Jeff Sharkey06bd5a82009-06-15 20:06:48 -070023import android.provider.ContactsContract.Contacts;
Evan Millar66388be2009-05-28 15:41:07 -070024import android.provider.ContactsContract.Data;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080025import android.view.LayoutInflater;
26import android.view.View;
27import android.view.ViewGroup;
28import android.widget.BaseAdapter;
29
30import java.util.ArrayList;
31
32public abstract class ContactEntryAdapter<E extends ContactEntryAdapter.Entry>
33 extends BaseAdapter {
34
Evan Millar66388be2009-05-28 15:41:07 -070035 public static final String[] AGGREGATE_PROJECTION = new String[] {
36 Aggregates.DISPLAY_NAME, // 0
37 Aggregates.STARRED, //1
Evan Millar2c1cc832009-07-13 11:08:06 -070038 Aggregates.PHOTO_ID, //2
39 Data._ID, //3
40 Data.CONTACT_ID, //4
Jeff Sharkeyc6ad3ab2009-07-21 19:30:15 -070041 Data.RES_PACKAGE, //5
Evan Millar2c1cc832009-07-13 11:08:06 -070042 Data.MIMETYPE, //6
43 Data.IS_PRIMARY, //7
44 Data.IS_SUPER_PRIMARY, //8
45 Data.DATA1, //9
46 Data.DATA2, //10
47 Data.DATA3, //11
48 Data.DATA4, //12
49 Data.DATA5, //13
50 Data.DATA6, //14
51 Data.DATA7, //15
52 Data.DATA8, //16
53 Data.DATA9, //17
54 Data.DATA10, //18
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080055 };
Evan Millar66388be2009-05-28 15:41:07 -070056 public static final int AGGREGATE_DISPLAY_NAME_COLUMN = 0;
57 public static final int AGGREGATE_STARRED_COLUMN = 1;
Evan Millar2c1cc832009-07-13 11:08:06 -070058 public static final int AGGREGATE_PHOTO_ID = 2;
59 public static final int DATA_ID_COLUMN = 3;
60 public static final int DATA_CONTACT_ID_COLUMN = 4;
61 public static final int DATA_PACKAGE_COLUMN = 5;
62 public static final int DATA_MIMETYPE_COLUMN = 6;
63 public static final int DATA_IS_PRIMARY_COLUMN = 7;
64 public static final int DATA_IS_SUPER_PRIMARY_COLUMN = 8;
65 public static final int DATA_1_COLUMN = 9;
66 public static final int DATA_2_COLUMN = 10;
67 public static final int DATA_3_COLUMN = 11;
68 public static final int DATA_4_COLUMN = 12;
69 public static final int DATA_5_COLUMN = 13;
70 public static final int DATA_6_COLUMN = 14;
71 public static final int DATA_7_COLUMN = 15;
72 public static final int DATA_8_COLUMN = 16;
73 public static final int DATA_9_COLUMN = 17;
74 public static final int DATA_10_COLUMN = 18;
Evan Millar45e0ed32009-06-01 16:44:38 -070075
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080076 protected ArrayList<ArrayList<E>> mSections;
77 protected LayoutInflater mInflater;
78 protected Context mContext;
79 protected boolean mSeparators;
80
81 /**
82 * Base class for adapter entries.
83 */
84 public static class Entry {
Evan Millar54a5c9f2009-06-23 17:41:09 -070085 public int type = -1;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080086 public String label;
87 public String data;
88 public Uri uri;
89 public long id = 0;
Dmitri Plotnikovb4491ee2009-06-15 09:31:02 -070090 public long contactId;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080091 public int maxLines = 1;
Evan Millar45e0ed32009-06-01 16:44:38 -070092 public String mimetype;
93
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080094 /**
95 * Helper for making subclasses parcelable.
96 */
97 protected void writeToParcel(Parcel p) {
Evan Millar54a5c9f2009-06-23 17:41:09 -070098 p.writeInt(type);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080099 p.writeString(label);
100 p.writeString(data);
101 p.writeParcelable(uri, 0);
102 p.writeLong(id);
103 p.writeInt(maxLines);
Evan Millar45e0ed32009-06-01 16:44:38 -0700104 p.writeString(mimetype);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800105 }
Evan Millar45e0ed32009-06-01 16:44:38 -0700106
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800107 /**
108 * Helper for making subclasses parcelable.
109 */
110 protected void readFromParcel(Parcel p) {
Evan Millar54a5c9f2009-06-23 17:41:09 -0700111 type = p.readInt();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800112 label = p.readString();
113 data = p.readString();
114 uri = p.readParcelable(null);
115 id = p.readLong();
116 maxLines = p.readInt();
Evan Millar45e0ed32009-06-01 16:44:38 -0700117 mimetype = p.readString();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800118 }
119 }
120
121 ContactEntryAdapter(Context context, ArrayList<ArrayList<E>> sections, boolean separators) {
122 mContext = context;
123 mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
124 mSections = sections;
125 mSeparators = separators;
126 }
127
128 /**
129 * Resets the section data.
Evan Millar45e0ed32009-06-01 16:44:38 -0700130 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800131 * @param sections the section data
132 */
133 public final void setSections(ArrayList<ArrayList<E>> sections, boolean separators) {
134 mSections = sections;
135 mSeparators = separators;
136 notifyDataSetChanged();
137 }
138
139 /**
140 * Resets the section data and returns the position of the given entry.
Evan Millar45e0ed32009-06-01 16:44:38 -0700141 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800142 * @param sections the section data
143 * @param entry the entry to return the position for
144 * @return the position of entry, or -1 if it isn't found
145 */
146 public final int setSections(ArrayList<ArrayList<E>> sections, E entry) {
147 mSections = sections;
148 notifyDataSetChanged();
149
150 int numSections = mSections.size();
151 int position = 0;
152 for (int i = 0; i < numSections; i++) {
153 ArrayList<E> section = mSections.get(i);
154 int sectionSize = section.size();
155 for (int j = 0; j < sectionSize; j++) {
156 E e = section.get(j);
157 if (e.equals(entry)) {
158 position += j;
159 return position;
160 }
161 }
162 position += sectionSize;
163 }
164 return -1;
165 }
166
167 /**
168 * @see android.widget.ListAdapter#getCount()
169 */
170 public final int getCount() {
171 return countEntries(mSections, mSeparators);
172 }
173
174 /**
175 * @see android.widget.ListAdapter#hasSeparators()
176 */
177 @Override
178 public final boolean areAllItemsEnabled() {
179 return mSeparators == false;
180 }
181
182 /**
183 * @see android.widget.ListAdapter#isSeparator(int)
184 */
185 @Override
186 public final boolean isEnabled(int position) {
187 if (!mSeparators) {
188 return true;
189 }
190
191 int numSections = mSections.size();
192 for (int i = 0; i < numSections; i++) {
193 ArrayList<E> section = mSections.get(i);
194 int sectionSize = section.size();
195 if (sectionSize == 1) {
196 // The section only contains a separator and nothing else, skip it
197 continue;
198 }
199 if (position == 0) {
200 // The first item in a section is always the separator
201 return false;
202 }
203 position -= sectionSize;
204 }
205 return true;
206 }
207
208 /**
209 * @see android.widget.ListAdapter#getItem(int)
210 */
211 public final Object getItem(int position) {
212 return getEntry(mSections, position, mSeparators);
213 }
214
215 /**
216 * Get the entry for the given position.
Evan Millar45e0ed32009-06-01 16:44:38 -0700217 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800218 * @param sections the list of sections
219 * @param position the position for the desired entry
220 * @return the ContactEntry for the given position
221 */
222 public final static <T extends Entry> T getEntry(ArrayList<ArrayList<T>> sections,
223 int position, boolean separators) {
224 int numSections = sections.size();
225 for (int i = 0; i < numSections; i++) {
226 ArrayList<T> section = sections.get(i);
227 int sectionSize = section.size();
228 if (separators && sectionSize == 1) {
229 // The section only contains a separator and nothing else, skip it
230 continue;
231 }
232 if (position < section.size()) {
233 return section.get(position);
234 }
235 position -= section.size();
236 }
237 return null;
238 }
239
240 /**
241 * Get the count of entries in all sections
Evan Millar45e0ed32009-06-01 16:44:38 -0700242 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800243 * @param sections the list of sections
244 * @return the count of entries in all sections
245 */
246 public static <T extends Entry> int countEntries(ArrayList<ArrayList<T>> sections,
247 boolean separators) {
248 int count = 0;
249 int numSections = sections.size();
250 for (int i = 0; i < numSections; i++) {
251 ArrayList<T> section = sections.get(i);
252 int sectionSize = section.size();
253 if (separators && sectionSize == 1) {
254 // The section only contains a separator and nothing else, skip it
255 continue;
256 }
257 count += sections.get(i).size();
258 }
259 return count;
260 }
261
262 /**
263 * @see android.widget.ListAdapter#getItemId(int)
264 */
265 public final long getItemId(int position) {
266 Entry entry = getEntry(mSections, position, mSeparators);
267 if (entry != null) {
268 return entry.id;
269 } else {
270 return -1;
271 }
272 }
273
274 /**
275 * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
276 */
277 public View getView(int position, View convertView, ViewGroup parent) {
278 View v;
279 if (convertView == null) {
280 v = newView(position, parent);
281 } else {
282 v = convertView;
283 }
284 bindView(v, getEntry(mSections, position, mSeparators));
285 return v;
286 }
287
288 /**
289 * Create a new view for an entry.
Evan Millar45e0ed32009-06-01 16:44:38 -0700290 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800291 * @parent the parent ViewGroup
292 * @return the newly created view
293 */
294 protected abstract View newView(int position, ViewGroup parent);
295
296 /**
297 * Binds the data from an entry to a view.
Evan Millar45e0ed32009-06-01 16:44:38 -0700298 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800299 * @param view the view to display the entry in
300 * @param entry the data to bind
301 */
302 protected abstract void bindView(View view, E entry);
303}