blob: 114793afa62a45dd49bef4611ae0cc788e56cc1d [file] [log] [blame]
Alexandre Lision064e1e02013-10-01 16:18:42 -04001package org.sflphone.adapters;
alisiond295ec22013-05-17 10:12:13 -04002
Alexandre Lisione1c96db2013-10-04 14:34:21 -04003import java.lang.ref.WeakReference;
alisiond295ec22013-05-17 10:12:13 -04004import java.util.ArrayList;
5import java.util.concurrent.ExecutorService;
6import java.util.concurrent.Executors;
7
Alexandre Lisione1c96db2013-10-04 14:34:21 -04008import org.sflphone.R;
9import org.sflphone.fragments.ContactListFragment;
Alexandre Lision064e1e02013-10-01 16:18:42 -040010import org.sflphone.model.CallContact;
Alexandre Lision691a1d62013-11-12 10:06:27 -050011import org.sflphone.views.stickylistheaders.StickyListHeadersAdapter;
Alexandre Lision064e1e02013-10-01 16:18:42 -040012
alisiond295ec22013-05-17 10:12:13 -040013import android.content.Context;
alisiond295ec22013-05-17 10:12:13 -040014import android.view.LayoutInflater;
15import android.view.View;
Alexandre Lisione1c96db2013-10-04 14:34:21 -040016import android.view.View.OnClickListener;
alisiond295ec22013-05-17 10:12:13 -040017import android.view.ViewGroup;
18import android.widget.BaseAdapter;
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -040019import android.widget.ImageButton;
alisiond295ec22013-05-17 10:12:13 -040020import android.widget.ImageView;
alisionf7053602013-07-09 10:25:20 -040021import android.widget.SectionIndexer;
alisiond295ec22013-05-17 10:12:13 -040022import android.widget.TextView;
Alexandre Lisionc59685a2013-10-04 16:36:36 -040023import android.widget.Toast;
alisiond295ec22013-05-17 10:12:13 -040024
Alexandre Lision691a1d62013-11-12 10:06:27 -050025public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAdapter, SectionIndexer {
alisiond295ec22013-05-17 10:12:13 -040026
27 private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
alisiond295ec22013-05-17 10:12:13 -040028 Context mContext;
29
Alexandre Lision691a1d62013-11-12 10:06:27 -050030 private ArrayList<CallContact> mContacts;
31 private int[] mSectionIndices;
32 private Character[] mSectionLetters;
Alexandre Lisione1c96db2013-10-04 14:34:21 -040033 WeakReference<ContactListFragment> parent;
Alexandre Lision691a1d62013-11-12 10:06:27 -050034 private LayoutInflater mInflater;
alisionf7053602013-07-09 10:25:20 -040035
Alexandre Lisione1c96db2013-10-04 14:34:21 -040036 // private static final String TAG = ContactsAdapter.class.getSimpleName();
alisiond295ec22013-05-17 10:12:13 -040037
Alexandre Lisione1c96db2013-10-04 14:34:21 -040038 public ContactsAdapter(ContactListFragment contactListFragment) {
alisiond295ec22013-05-17 10:12:13 -040039 super();
Alexandre Lisione1c96db2013-10-04 14:34:21 -040040 mContext = contactListFragment.getActivity();
Alexandre Lision691a1d62013-11-12 10:06:27 -050041 mInflater = LayoutInflater.from(mContext);
Alexandre Lisione1c96db2013-10-04 14:34:21 -040042 parent = new WeakReference<ContactListFragment>(contactListFragment);
Alexandre Lision691a1d62013-11-12 10:06:27 -050043 mContacts = new ArrayList<CallContact>();
44 mSectionIndices = getSectionIndices();
45 mSectionLetters = getSectionLetters();
alisiond295ec22013-05-17 10:12:13 -040046 }
47
Alexandre Lision691a1d62013-11-12 10:06:27 -050048 public static final int TYPE_HEADER = 0;
49 public static final int TYPE_CONTACT = 1;
50
51 private int[] getSectionIndices() {
52 ArrayList<Integer> sectionIndices = new ArrayList<Integer>();
53 if (mContacts.isEmpty())
54 return new int[0];
55 char lastFirstChar = mContacts.get(0).getmDisplayName().charAt(0);
56 sectionIndices.add(0);
57 for (int i = 1; i < mContacts.size(); i++) {
58 if (mContacts.get(i).getmDisplayName().charAt(0) != lastFirstChar) {
59 lastFirstChar = mContacts.get(i).getmDisplayName().charAt(0);
60 sectionIndices.add(i);
61 }
62 }
63 int[] sections = new int[sectionIndices.size()];
64 for (int i = 0; i < sectionIndices.size(); i++) {
65 sections[i] = sectionIndices.get(i);
66 }
67 return sections;
68 }
69
70 private Character[] getSectionLetters() {
71 Character[] letters = new Character[mSectionIndices.length];
72 for (int i = 0; i < mSectionIndices.length; i++) {
73 letters[i] = mContacts.get(mSectionIndices[i]).getmDisplayName().charAt(0);
74 }
75 return letters;
76 }
alisionf7053602013-07-09 10:25:20 -040077
78 @Override
Alexandre Lision691a1d62013-11-12 10:06:27 -050079 public View getView(int position, View convertView, ViewGroup root) {
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -040080 ContactView entryView;
Alexandre Lision691a1d62013-11-12 10:06:27 -050081
alisionf7053602013-07-09 10:25:20 -040082 if (convertView == null) {
Alexandre Lision691a1d62013-11-12 10:06:27 -050083 convertView = mInflater.inflate(R.layout.item_contact, null);
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -040084
85 entryView = new ContactView();
86 entryView.quick_starred = (ImageButton) convertView.findViewById(R.id.quick_starred);
87 entryView.quick_edit = (ImageButton) convertView.findViewById(R.id.quick_edit);
88 entryView.quick_discard = (ImageButton) convertView.findViewById(R.id.quick_discard);
89 entryView.quick_call = (ImageButton) convertView.findViewById(R.id.quick_call);
90 entryView.quick_msg = (ImageButton) convertView.findViewById(R.id.quick_message);
91 entryView.photo = (ImageView) convertView.findViewById(R.id.photo);
92 entryView.display_name = (TextView) convertView.findViewById(R.id.display_name);
93 convertView.setTag(entryView);
94 } else {
95 entryView = (ContactView) convertView.getTag();
alisionf7053602013-07-09 10:25:20 -040096 }
97
Alexandre Lision691a1d62013-11-12 10:06:27 -050098 final CallContact item = mContacts.get(position);
alisionf7053602013-07-09 10:25:20 -040099
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400100 entryView.display_name.setText(item.getmDisplayName());
alisionf7053602013-07-09 10:25:20 -0400101
Alexandre Lision691a1d62013-11-12 10:06:27 -0500102 if (item.hasPhoto()) {
Alexandre Lision35c3cbb2013-11-04 17:11:54 -0500103 entryView.photo.setImageBitmap(item.getPhoto());
104 } else {
105 infos_fetcher.execute(new ContactPictureTask(mContext, entryView.photo, item));
106 }
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400107
108 entryView.quick_call.setOnClickListener(new OnClickListener() {
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400109
110 @Override
111 public void onClick(View v) {
112 parent.get().mCallbacks.onCallContact(item);
113
114 }
115 });
Alexandre Lision691a1d62013-11-12 10:06:27 -0500116
Alexandre Lisione168d4a2013-10-24 12:32:59 -0400117 entryView.quick_msg.setOnClickListener(new OnClickListener() {
118
119 @Override
120 public void onClick(View v) {
121 parent.get().mCallbacks.onTextContact(item);
122 }
123 });
Alexandre Lision691a1d62013-11-12 10:06:27 -0500124
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400125 entryView.quick_starred.setOnClickListener(new OnClickListener() {
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400126
127 @Override
128 public void onClick(View v) {
129 Toast.makeText(mContext, "Coming soon", Toast.LENGTH_SHORT).show();
130 }
131 });
Alexandre Lision691a1d62013-11-12 10:06:27 -0500132
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400133 entryView.quick_edit.setOnClickListener(new OnClickListener() {
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400134
135 @Override
136 public void onClick(View v) {
137 parent.get().mCallbacks.onEditContact(item);
138
139 }
140 });
Alexandre Lision691a1d62013-11-12 10:06:27 -0500141
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400142 entryView.quick_discard.setOnClickListener(new OnClickListener() {
Alexandre Lisionc59685a2013-10-04 16:36:36 -0400143
144 @Override
145 public void onClick(View v) {
146 Toast.makeText(mContext, "Coming soon", Toast.LENGTH_SHORT).show();
147
148 }
149 });
Alexandre Lision691a1d62013-11-12 10:06:27 -0500150
Alexandre Lisione168d4a2013-10-24 12:32:59 -0400151 entryView.quick_edit.setClickable(false);
152 entryView.quick_discard.setClickable(false);
153 entryView.quick_starred.setClickable(false);
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400154
alisionf7053602013-07-09 10:25:20 -0400155 return convertView;
alisiond295ec22013-05-17 10:12:13 -0400156 }
Alexandre Lision691a1d62013-11-12 10:06:27 -0500157
Alexandre Lisiond5dbcdf2013-10-07 14:13:09 -0400158 /*********************
159 * ViewHolder Pattern
160 *********************/
161 public class ContactView {
162 ImageButton quick_starred, quick_edit, quick_discard, quick_call, quick_msg;
163 ImageView photo;
164 TextView display_name;
165 }
alisiond295ec22013-05-17 10:12:13 -0400166
167 @Override
168 public int getCount() {
Alexandre Lision691a1d62013-11-12 10:06:27 -0500169 return mContacts.size();
alisionf7053602013-07-09 10:25:20 -0400170 }
171
172 @Override
173 public int getViewTypeCount() {
174 return 2;
175 }
176
alisionf7053602013-07-09 10:25:20 -0400177 @Override
178 public long getItemId(int position) {
179 return 0;
180 }
181
Alexandre Lision691a1d62013-11-12 10:06:27 -0500182 @Override
183 public View getHeaderView(int position, View convertView, ViewGroup parent) {
184 HeaderViewHolder holder;
185
186 if (convertView == null) {
187 holder = new HeaderViewHolder();
188 convertView = mInflater.inflate(R.layout.header, parent, false);
189 holder.text = (TextView) convertView.findViewById(R.id.header_letter);
190 convertView.setTag(holder);
191 } else {
192 holder = (HeaderViewHolder) convertView.getTag();
193 }
194
195 // set header text as first char in name
196 char headerChar = mContacts.get(position).getmDisplayName().subSequence(0, 1).charAt(0);
197
198 holder.text.setText("" + headerChar);
199
200 return convertView;
201
alisionf7053602013-07-09 10:25:20 -0400202 }
203
Alexandre Lision691a1d62013-11-12 10:06:27 -0500204 class HeaderViewHolder {
205 TextView text;
alisionf7053602013-07-09 10:25:20 -0400206 }
207
Alexandre Lision691a1d62013-11-12 10:06:27 -0500208 @Override
209 public long getHeaderId(int position) {
210 // return the first character of the name as ID because this is what
211 // headers are based upon
212 return mContacts.get(position).getmDisplayName().subSequence(0, 1).charAt(0);
alisionf7053602013-07-09 10:25:20 -0400213 }
214
alisionf7053602013-07-09 10:25:20 -0400215 @Override
216 public int getPositionForSection(int section) {
Alexandre Lision691a1d62013-11-12 10:06:27 -0500217 if (section >= mSectionIndices.length) {
218 section = mSectionIndices.length - 1;
219 } else if (section < 0) {
220 section = 0;
221 }
222 return mSectionIndices[section];
alisionf7053602013-07-09 10:25:20 -0400223 }
224
225 @Override
226 public int getSectionForPosition(int position) {
Alexandre Lision691a1d62013-11-12 10:06:27 -0500227 for (int i = 0; i < mSectionIndices.length; i++) {
228 if (position < mSectionIndices[i]) {
229 return i - 1;
230 }
231 }
232 return mSectionIndices.length - 1;
alisionf7053602013-07-09 10:25:20 -0400233 }
234
235 @Override
236 public Object[] getSections() {
Alexandre Lision691a1d62013-11-12 10:06:27 -0500237 return mSectionLetters;
alisiond295ec22013-05-17 10:12:13 -0400238 }
239
240 @Override
Alexandre Lision691a1d62013-11-12 10:06:27 -0500241 public CallContact getItem(int position) {
242 return mContacts.get(position);
alisiond295ec22013-05-17 10:12:13 -0400243 }
Alexandre Lisione1c96db2013-10-04 14:34:21 -0400244
Alexandre Lision691a1d62013-11-12 10:06:27 -0500245 public void clear() {
246 mContacts = new ArrayList<CallContact>();
247 mSectionIndices = new int[0];
248 mSectionLetters = new Character[0];
249 notifyDataSetChanged();
250 }
alisiond295ec22013-05-17 10:12:13 -0400251
Alexandre Lision691a1d62013-11-12 10:06:27 -0500252 public void restore() {
253 mContacts = new ArrayList<CallContact>();
254 mSectionIndices = getSectionIndices();
255 mSectionLetters = getSectionLetters();
256 notifyDataSetChanged();
257 }
alisiond295ec22013-05-17 10:12:13 -0400258
Alexandre Lision691a1d62013-11-12 10:06:27 -0500259 public void addAll(ArrayList<CallContact> tmp) {
260 mContacts.addAll(tmp);
261 mSectionIndices = getSectionIndices();
262 mSectionLetters = getSectionLetters();
263 notifyDataSetChanged();
alisiond295ec22013-05-17 10:12:13 -0400264 }
265
266}