blob: 11c862a81457dcc811cb1c0b1e5f11d23af7cdb8 [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
Dmitri Plotnikovb4491ee2009-06-15 09:31:02 -070038 Data._ID, //2
39 Data.CONTACT_ID, //3
Jeff Sharkey06bd5a82009-06-15 20:06:48 -070040 Contacts.PACKAGE, //4
Dmitri Plotnikovb4491ee2009-06-15 09:31:02 -070041 Data.MIMETYPE, //5
42 Data.IS_PRIMARY, //6
43 Data.IS_SUPER_PRIMARY, //7
44 Data.DATA1, //8
45 Data.DATA2, //9
46 Data.DATA3, //10
47 Data.DATA4, //11
48 Data.DATA5, //12
49 Data.DATA6, //13
50 Data.DATA7, //14
51 Data.DATA8, //15
52 Data.DATA9, //16
53 Data.DATA10, //17
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080054 };
Evan Millar66388be2009-05-28 15:41:07 -070055 public static final int AGGREGATE_DISPLAY_NAME_COLUMN = 0;
56 public static final int AGGREGATE_STARRED_COLUMN = 1;
57 public static final int DATA_ID_COLUMN = 2;
Dmitri Plotnikovb4491ee2009-06-15 09:31:02 -070058 public static final int DATA_CONTACT_ID_COLUMN = 3;
59 public static final int DATA_PACKAGE_COLUMN = 4;
60 public static final int DATA_MIMETYPE_COLUMN = 5;
61 public static final int DATA_IS_PRIMARY_COLUMN = 6;
62 public static final int DATA_IS_SUPER_PRIMARY_COLUMN = 7;
63 public static final int DATA_1_COLUMN = 8;
64 public static final int DATA_2_COLUMN = 9;
65 public static final int DATA_3_COLUMN = 10;
66 public static final int DATA_4_COLUMN = 11;
67 public static final int DATA_5_COLUMN = 12;
68 public static final int DATA_6_COLUMN = 13;
69 public static final int DATA_7_COLUMN = 14;
70 public static final int DATA_8_COLUMN = 15;
71 public static final int DATA_9_COLUMN = 16;
72 public static final int DATA_10_COLUMN = 17;
Evan Millar45e0ed32009-06-01 16:44:38 -070073
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080074 protected ArrayList<ArrayList<E>> mSections;
75 protected LayoutInflater mInflater;
76 protected Context mContext;
77 protected boolean mSeparators;
78
79 /**
80 * Base class for adapter entries.
81 */
82 public static class Entry {
Evan Millar54a5c9f2009-06-23 17:41:09 -070083 public int type = -1;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080084 public String label;
85 public String data;
86 public Uri uri;
87 public long id = 0;
Dmitri Plotnikovb4491ee2009-06-15 09:31:02 -070088 public long contactId;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080089 public int maxLines = 1;
Evan Millar45e0ed32009-06-01 16:44:38 -070090 public String mimetype;
91
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080092 /**
93 * Helper for making subclasses parcelable.
94 */
95 protected void writeToParcel(Parcel p) {
Evan Millar54a5c9f2009-06-23 17:41:09 -070096 p.writeInt(type);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080097 p.writeString(label);
98 p.writeString(data);
99 p.writeParcelable(uri, 0);
100 p.writeLong(id);
101 p.writeInt(maxLines);
Evan Millar45e0ed32009-06-01 16:44:38 -0700102 p.writeString(mimetype);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800103 }
Evan Millar45e0ed32009-06-01 16:44:38 -0700104
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800105 /**
106 * Helper for making subclasses parcelable.
107 */
108 protected void readFromParcel(Parcel p) {
Evan Millar54a5c9f2009-06-23 17:41:09 -0700109 type = p.readInt();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800110 label = p.readString();
111 data = p.readString();
112 uri = p.readParcelable(null);
113 id = p.readLong();
114 maxLines = p.readInt();
Evan Millar45e0ed32009-06-01 16:44:38 -0700115 mimetype = p.readString();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800116 }
117 }
118
119 ContactEntryAdapter(Context context, ArrayList<ArrayList<E>> sections, boolean separators) {
120 mContext = context;
121 mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
122 mSections = sections;
123 mSeparators = separators;
124 }
125
126 /**
127 * Resets the section data.
Evan Millar45e0ed32009-06-01 16:44:38 -0700128 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800129 * @param sections the section data
130 */
131 public final void setSections(ArrayList<ArrayList<E>> sections, boolean separators) {
132 mSections = sections;
133 mSeparators = separators;
134 notifyDataSetChanged();
135 }
136
137 /**
138 * Resets the section data and returns the position of the given entry.
Evan Millar45e0ed32009-06-01 16:44:38 -0700139 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800140 * @param sections the section data
141 * @param entry the entry to return the position for
142 * @return the position of entry, or -1 if it isn't found
143 */
144 public final int setSections(ArrayList<ArrayList<E>> sections, E entry) {
145 mSections = sections;
146 notifyDataSetChanged();
147
148 int numSections = mSections.size();
149 int position = 0;
150 for (int i = 0; i < numSections; i++) {
151 ArrayList<E> section = mSections.get(i);
152 int sectionSize = section.size();
153 for (int j = 0; j < sectionSize; j++) {
154 E e = section.get(j);
155 if (e.equals(entry)) {
156 position += j;
157 return position;
158 }
159 }
160 position += sectionSize;
161 }
162 return -1;
163 }
164
165 /**
166 * @see android.widget.ListAdapter#getCount()
167 */
168 public final int getCount() {
169 return countEntries(mSections, mSeparators);
170 }
171
172 /**
173 * @see android.widget.ListAdapter#hasSeparators()
174 */
175 @Override
176 public final boolean areAllItemsEnabled() {
177 return mSeparators == false;
178 }
179
180 /**
181 * @see android.widget.ListAdapter#isSeparator(int)
182 */
183 @Override
184 public final boolean isEnabled(int position) {
185 if (!mSeparators) {
186 return true;
187 }
188
189 int numSections = mSections.size();
190 for (int i = 0; i < numSections; i++) {
191 ArrayList<E> section = mSections.get(i);
192 int sectionSize = section.size();
193 if (sectionSize == 1) {
194 // The section only contains a separator and nothing else, skip it
195 continue;
196 }
197 if (position == 0) {
198 // The first item in a section is always the separator
199 return false;
200 }
201 position -= sectionSize;
202 }
203 return true;
204 }
205
206 /**
207 * @see android.widget.ListAdapter#getItem(int)
208 */
209 public final Object getItem(int position) {
210 return getEntry(mSections, position, mSeparators);
211 }
212
213 /**
214 * Get the entry for the given position.
Evan Millar45e0ed32009-06-01 16:44:38 -0700215 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800216 * @param sections the list of sections
217 * @param position the position for the desired entry
218 * @return the ContactEntry for the given position
219 */
220 public final static <T extends Entry> T getEntry(ArrayList<ArrayList<T>> sections,
221 int position, boolean separators) {
222 int numSections = sections.size();
223 for (int i = 0; i < numSections; i++) {
224 ArrayList<T> section = sections.get(i);
225 int sectionSize = section.size();
226 if (separators && sectionSize == 1) {
227 // The section only contains a separator and nothing else, skip it
228 continue;
229 }
230 if (position < section.size()) {
231 return section.get(position);
232 }
233 position -= section.size();
234 }
235 return null;
236 }
237
238 /**
239 * Get the count of entries in all sections
Evan Millar45e0ed32009-06-01 16:44:38 -0700240 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800241 * @param sections the list of sections
242 * @return the count of entries in all sections
243 */
244 public static <T extends Entry> int countEntries(ArrayList<ArrayList<T>> sections,
245 boolean separators) {
246 int count = 0;
247 int numSections = sections.size();
248 for (int i = 0; i < numSections; i++) {
249 ArrayList<T> section = sections.get(i);
250 int sectionSize = section.size();
251 if (separators && sectionSize == 1) {
252 // The section only contains a separator and nothing else, skip it
253 continue;
254 }
255 count += sections.get(i).size();
256 }
257 return count;
258 }
259
260 /**
261 * @see android.widget.ListAdapter#getItemId(int)
262 */
263 public final long getItemId(int position) {
264 Entry entry = getEntry(mSections, position, mSeparators);
265 if (entry != null) {
266 return entry.id;
267 } else {
268 return -1;
269 }
270 }
271
272 /**
273 * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
274 */
275 public View getView(int position, View convertView, ViewGroup parent) {
276 View v;
277 if (convertView == null) {
278 v = newView(position, parent);
279 } else {
280 v = convertView;
281 }
282 bindView(v, getEntry(mSections, position, mSeparators));
283 return v;
284 }
285
286 /**
287 * Create a new view for an entry.
Evan Millar45e0ed32009-06-01 16:44:38 -0700288 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800289 * @parent the parent ViewGroup
290 * @return the newly created view
291 */
292 protected abstract View newView(int position, ViewGroup parent);
293
294 /**
295 * Binds the data from an entry to a view.
Evan Millar45e0ed32009-06-01 16:44:38 -0700296 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800297 * @param view the view to display the entry in
298 * @param entry the data to bind
299 */
300 protected abstract void bindView(View view, E entry);
301}