blob: 64f2585f9bd1fa29027e0c433676ec2282db0d2a [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;
23import android.provider.ContactsContract.Data;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080024import android.view.LayoutInflater;
25import android.view.View;
26import android.view.ViewGroup;
27import android.widget.BaseAdapter;
28
29import java.util.ArrayList;
30
31public abstract class ContactEntryAdapter<E extends ContactEntryAdapter.Entry>
32 extends BaseAdapter {
33
Evan Millar66388be2009-05-28 15:41:07 -070034 public static final String[] AGGREGATE_PROJECTION = new String[] {
35 Aggregates.DISPLAY_NAME, // 0
36 Aggregates.STARRED, //1
37 Data._ID, // 2
38 Data.PACKAGE, //3
39 Data.MIMETYPE, //4
40 Data.DATA1, //5
41 Data.DATA2, //6
42 Data.DATA3, //7
43 Data.DATA4, //8
44 Data.DATA5, //9
45 Data.DATA6, //10
46 Data.DATA7, //11
47 Data.DATA8, //12
48 Data.DATA9, //13
49 Data.DATA10, //14
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080050 };
Evan Millar66388be2009-05-28 15:41:07 -070051 public static final int AGGREGATE_DISPLAY_NAME_COLUMN = 0;
52 public static final int AGGREGATE_STARRED_COLUMN = 1;
53 public static final int DATA_ID_COLUMN = 2;
54 public static final int DATA_PACKAGE_COLUMN = 3;
55 public static final int DATA_MIMETYPE_COLUMN = 4;
56 public static final int DATA_1_COLUMN = 5;
57 public static final int DATA_2_COLUMN = 6;
58 public static final int DATA_3_COLUMN = 7;
59 public static final int DATA_4_COLUMN = 8;
60 public static final int DATA_5_COLUMN = 9;
61 public static final int DATA_6_COLUMN = 10;
62 public static final int DATA_7_COLUMN = 11;
63 public static final int DATA_8_COLUMN = 12;
64 public static final int DATA_9_COLUMN = 13;
65 public static final int DATA_10_COLUMN = 14;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080066
67 protected ArrayList<ArrayList<E>> mSections;
68 protected LayoutInflater mInflater;
69 protected Context mContext;
70 protected boolean mSeparators;
71
72 /**
73 * Base class for adapter entries.
74 */
75 public static class Entry {
76 /** Details from the person table */
77 public static final int KIND_CONTACT = -1;
78 /** Synthesized phone entry that will send an SMS instead of call the number */
79 public static final int KIND_SMS = -2;
80 /** A section separator */
The Android Open Source Projectcac191e2009-03-18 22:20:27 -070081 public static final int KIND_SEPARATOR = -3;
82 /** Signifies a group row that is stored in the group membership table */
83 public static final int KIND_GROUP = -4;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080084
85 public String label;
86 public String data;
87 public Uri uri;
88 public long id = 0;
89 public int maxLines = 1;
90 public int kind;
91
92 /**
93 * Helper for making subclasses parcelable.
94 */
95 protected void writeToParcel(Parcel p) {
96 p.writeString(label);
97 p.writeString(data);
98 p.writeParcelable(uri, 0);
99 p.writeLong(id);
100 p.writeInt(maxLines);
101 p.writeInt(kind);
102 }
103
104 /**
105 * Helper for making subclasses parcelable.
106 */
107 protected void readFromParcel(Parcel p) {
108 label = p.readString();
109 data = p.readString();
110 uri = p.readParcelable(null);
111 id = p.readLong();
112 maxLines = p.readInt();
113 kind = p.readInt();
114 }
115 }
116
117 ContactEntryAdapter(Context context, ArrayList<ArrayList<E>> sections, boolean separators) {
118 mContext = context;
119 mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
120 mSections = sections;
121 mSeparators = separators;
122 }
123
124 /**
125 * Resets the section data.
126 *
127 * @param sections the section data
128 */
129 public final void setSections(ArrayList<ArrayList<E>> sections, boolean separators) {
130 mSections = sections;
131 mSeparators = separators;
132 notifyDataSetChanged();
133 }
134
135 /**
136 * Resets the section data and returns the position of the given entry.
137 *
138 * @param sections the section data
139 * @param entry the entry to return the position for
140 * @return the position of entry, or -1 if it isn't found
141 */
142 public final int setSections(ArrayList<ArrayList<E>> sections, E entry) {
143 mSections = sections;
144 notifyDataSetChanged();
145
146 int numSections = mSections.size();
147 int position = 0;
148 for (int i = 0; i < numSections; i++) {
149 ArrayList<E> section = mSections.get(i);
150 int sectionSize = section.size();
151 for (int j = 0; j < sectionSize; j++) {
152 E e = section.get(j);
153 if (e.equals(entry)) {
154 position += j;
155 return position;
156 }
157 }
158 position += sectionSize;
159 }
160 return -1;
161 }
162
163 /**
164 * @see android.widget.ListAdapter#getCount()
165 */
166 public final int getCount() {
167 return countEntries(mSections, mSeparators);
168 }
169
170 /**
171 * @see android.widget.ListAdapter#hasSeparators()
172 */
173 @Override
174 public final boolean areAllItemsEnabled() {
175 return mSeparators == false;
176 }
177
178 /**
179 * @see android.widget.ListAdapter#isSeparator(int)
180 */
181 @Override
182 public final boolean isEnabled(int position) {
183 if (!mSeparators) {
184 return true;
185 }
186
187 int numSections = mSections.size();
188 for (int i = 0; i < numSections; i++) {
189 ArrayList<E> section = mSections.get(i);
190 int sectionSize = section.size();
191 if (sectionSize == 1) {
192 // The section only contains a separator and nothing else, skip it
193 continue;
194 }
195 if (position == 0) {
196 // The first item in a section is always the separator
197 return false;
198 }
199 position -= sectionSize;
200 }
201 return true;
202 }
203
204 /**
205 * @see android.widget.ListAdapter#getItem(int)
206 */
207 public final Object getItem(int position) {
208 return getEntry(mSections, position, mSeparators);
209 }
210
211 /**
212 * Get the entry for the given position.
213 *
214 * @param sections the list of sections
215 * @param position the position for the desired entry
216 * @return the ContactEntry for the given position
217 */
218 public final static <T extends Entry> T getEntry(ArrayList<ArrayList<T>> sections,
219 int position, boolean separators) {
220 int numSections = sections.size();
221 for (int i = 0; i < numSections; i++) {
222 ArrayList<T> section = sections.get(i);
223 int sectionSize = section.size();
224 if (separators && sectionSize == 1) {
225 // The section only contains a separator and nothing else, skip it
226 continue;
227 }
228 if (position < section.size()) {
229 return section.get(position);
230 }
231 position -= section.size();
232 }
233 return null;
234 }
235
236 /**
237 * Get the count of entries in all sections
238 *
239 * @param sections the list of sections
240 * @return the count of entries in all sections
241 */
242 public static <T extends Entry> int countEntries(ArrayList<ArrayList<T>> sections,
243 boolean separators) {
244 int count = 0;
245 int numSections = sections.size();
246 for (int i = 0; i < numSections; i++) {
247 ArrayList<T> section = sections.get(i);
248 int sectionSize = section.size();
249 if (separators && sectionSize == 1) {
250 // The section only contains a separator and nothing else, skip it
251 continue;
252 }
253 count += sections.get(i).size();
254 }
255 return count;
256 }
257
258 /**
259 * @see android.widget.ListAdapter#getItemId(int)
260 */
261 public final long getItemId(int position) {
262 Entry entry = getEntry(mSections, position, mSeparators);
263 if (entry != null) {
264 return entry.id;
265 } else {
266 return -1;
267 }
268 }
269
270 /**
271 * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
272 */
273 public View getView(int position, View convertView, ViewGroup parent) {
274 View v;
275 if (convertView == null) {
276 v = newView(position, parent);
277 } else {
278 v = convertView;
279 }
280 bindView(v, getEntry(mSections, position, mSeparators));
281 return v;
282 }
283
284 /**
285 * Create a new view for an entry.
286 *
287 * @parent the parent ViewGroup
288 * @return the newly created view
289 */
290 protected abstract View newView(int position, ViewGroup parent);
291
292 /**
293 * Binds the data from an entry to a view.
294 *
295 * @param view the view to display the entry in
296 * @param entry the data to bind
297 */
298 protected abstract void bindView(View view, E entry);
299}