blob: 90a41ca7f20f8d334ac2bc76d451d2e597303339 [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;
Dmitri Plotnikove1cd6792009-07-27 20:28:17 -070022import android.provider.ContactsContract.Contacts;
Evan Millar66388be2009-05-28 15:41:07 -070023import 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
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080034 protected ArrayList<ArrayList<E>> mSections;
35 protected LayoutInflater mInflater;
36 protected Context mContext;
37 protected boolean mSeparators;
38
39 /**
40 * Base class for adapter entries.
41 */
42 public static class Entry {
Evan Millar54a5c9f2009-06-23 17:41:09 -070043 public int type = -1;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080044 public String label;
45 public String data;
46 public Uri uri;
47 public long id = 0;
Dmitri Plotnikovb4491ee2009-06-15 09:31:02 -070048 public long contactId;
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080049 public int maxLines = 1;
Evan Millar45e0ed32009-06-01 16:44:38 -070050 public String mimetype;
51
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080052 /**
53 * Helper for making subclasses parcelable.
54 */
55 protected void writeToParcel(Parcel p) {
Evan Millar54a5c9f2009-06-23 17:41:09 -070056 p.writeInt(type);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080057 p.writeString(label);
58 p.writeString(data);
59 p.writeParcelable(uri, 0);
60 p.writeLong(id);
61 p.writeInt(maxLines);
Evan Millar45e0ed32009-06-01 16:44:38 -070062 p.writeString(mimetype);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080063 }
Evan Millar45e0ed32009-06-01 16:44:38 -070064
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080065 /**
66 * Helper for making subclasses parcelable.
67 */
68 protected void readFromParcel(Parcel p) {
Dmitri Plotnikovcebe8352010-03-15 10:44:42 -070069 final ClassLoader loader = getClass().getClassLoader();
Evan Millar54a5c9f2009-06-23 17:41:09 -070070 type = p.readInt();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080071 label = p.readString();
72 data = p.readString();
Dmitri Plotnikovcebe8352010-03-15 10:44:42 -070073 uri = p.readParcelable(loader);
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080074 id = p.readLong();
75 maxLines = p.readInt();
Evan Millar45e0ed32009-06-01 16:44:38 -070076 mimetype = p.readString();
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080077 }
78 }
79
Daniel Lehmann4cd94412010-04-08 16:44:36 -070080 protected ContactEntryAdapter(Context context, ArrayList<ArrayList<E>> sections,
81 boolean separators) {
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080082 mContext = context;
83 mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
84 mSections = sections;
85 mSeparators = separators;
86 }
87
88 /**
89 * Resets the section data.
Evan Millar45e0ed32009-06-01 16:44:38 -070090 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -080091 * @param sections the section data
92 */
93 public final void setSections(ArrayList<ArrayList<E>> sections, boolean separators) {
94 mSections = sections;
95 mSeparators = separators;
96 notifyDataSetChanged();
97 }
98
99 /**
100 * Resets the section data and returns the position of the given entry.
Evan Millar45e0ed32009-06-01 16:44:38 -0700101 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800102 * @param sections the section data
103 * @param entry the entry to return the position for
104 * @return the position of entry, or -1 if it isn't found
105 */
106 public final int setSections(ArrayList<ArrayList<E>> sections, E entry) {
107 mSections = sections;
108 notifyDataSetChanged();
109
110 int numSections = mSections.size();
111 int position = 0;
112 for (int i = 0; i < numSections; i++) {
113 ArrayList<E> section = mSections.get(i);
114 int sectionSize = section.size();
115 for (int j = 0; j < sectionSize; j++) {
116 E e = section.get(j);
117 if (e.equals(entry)) {
118 position += j;
119 return position;
120 }
121 }
122 position += sectionSize;
123 }
124 return -1;
125 }
126
127 /**
128 * @see android.widget.ListAdapter#getCount()
129 */
130 public final int getCount() {
131 return countEntries(mSections, mSeparators);
132 }
133
134 /**
135 * @see android.widget.ListAdapter#hasSeparators()
136 */
137 @Override
138 public final boolean areAllItemsEnabled() {
139 return mSeparators == false;
140 }
141
142 /**
143 * @see android.widget.ListAdapter#isSeparator(int)
144 */
145 @Override
146 public final boolean isEnabled(int position) {
147 if (!mSeparators) {
148 return true;
149 }
150
151 int numSections = mSections.size();
152 for (int i = 0; i < numSections; i++) {
153 ArrayList<E> section = mSections.get(i);
154 int sectionSize = section.size();
155 if (sectionSize == 1) {
156 // The section only contains a separator and nothing else, skip it
157 continue;
158 }
159 if (position == 0) {
160 // The first item in a section is always the separator
161 return false;
162 }
163 position -= sectionSize;
164 }
165 return true;
166 }
167
168 /**
169 * @see android.widget.ListAdapter#getItem(int)
170 */
171 public final Object getItem(int position) {
172 return getEntry(mSections, position, mSeparators);
173 }
174
175 /**
176 * Get the entry for the given position.
Evan Millar45e0ed32009-06-01 16:44:38 -0700177 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800178 * @param sections the list of sections
179 * @param position the position for the desired entry
180 * @return the ContactEntry for the given position
181 */
182 public final static <T extends Entry> T getEntry(ArrayList<ArrayList<T>> sections,
183 int position, boolean separators) {
184 int numSections = sections.size();
185 for (int i = 0; i < numSections; i++) {
186 ArrayList<T> section = sections.get(i);
187 int sectionSize = section.size();
188 if (separators && sectionSize == 1) {
189 // The section only contains a separator and nothing else, skip it
190 continue;
191 }
192 if (position < section.size()) {
193 return section.get(position);
194 }
195 position -= section.size();
196 }
197 return null;
198 }
199
200 /**
201 * Get the count of entries in all sections
Evan Millar45e0ed32009-06-01 16:44:38 -0700202 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800203 * @param sections the list of sections
204 * @return the count of entries in all sections
205 */
206 public static <T extends Entry> int countEntries(ArrayList<ArrayList<T>> sections,
207 boolean separators) {
208 int count = 0;
209 int numSections = sections.size();
210 for (int i = 0; i < numSections; i++) {
211 ArrayList<T> section = sections.get(i);
212 int sectionSize = section.size();
213 if (separators && sectionSize == 1) {
214 // The section only contains a separator and nothing else, skip it
215 continue;
216 }
217 count += sections.get(i).size();
218 }
219 return count;
220 }
221
222 /**
223 * @see android.widget.ListAdapter#getItemId(int)
224 */
225 public final long getItemId(int position) {
226 Entry entry = getEntry(mSections, position, mSeparators);
227 if (entry != null) {
228 return entry.id;
229 } else {
230 return -1;
231 }
232 }
233
234 /**
235 * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
236 */
237 public View getView(int position, View convertView, ViewGroup parent) {
238 View v;
239 if (convertView == null) {
240 v = newView(position, parent);
241 } else {
242 v = convertView;
243 }
244 bindView(v, getEntry(mSections, position, mSeparators));
245 return v;
246 }
247
248 /**
249 * Create a new view for an entry.
Evan Millar45e0ed32009-06-01 16:44:38 -0700250 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800251 * @parent the parent ViewGroup
252 * @return the newly created view
253 */
254 protected abstract View newView(int position, ViewGroup parent);
255
256 /**
257 * Binds the data from an entry to a view.
Evan Millar45e0ed32009-06-01 16:44:38 -0700258 *
The Android Open Source Project7aa0e4c2009-03-03 19:32:21 -0800259 * @param view the view to display the entry in
260 * @param entry the data to bind
261 */
262 protected abstract void bindView(View view, E entry);
263}