| /* |
| * Copyright (C) 2004-2013 Savoir-Faire Linux Inc. |
| * |
| * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com> |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 3 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| * |
| * Additional permission under GNU GPL version 3 section 7: |
| * |
| * If you modify this program, or any covered work, by linking or |
| * combining it with the OpenSSL project's OpenSSL library (or a |
| * modified version of that library), containing parts covered by the |
| * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. |
| * grants you additional permission to convey the resulting work. |
| * Corresponding Source for a non-source form of such a combination |
| * shall include the source code for the parts of OpenSSL used as well |
| * as that of the covered work. |
| */ |
| |
| package org.sflphone.adapters; |
| |
| import java.lang.ref.WeakReference; |
| import java.util.ArrayList; |
| import java.util.concurrent.ExecutorService; |
| import java.util.concurrent.Executors; |
| |
| import org.sflphone.R; |
| import org.sflphone.fragments.ContactListFragment; |
| import org.sflphone.model.CallContact; |
| import org.sflphone.views.stickylistheaders.StickyListHeadersAdapter; |
| |
| import android.content.Context; |
| import android.view.LayoutInflater; |
| import android.view.View; |
| import android.view.View.OnClickListener; |
| import android.view.ViewGroup; |
| import android.widget.BaseAdapter; |
| import android.widget.ImageButton; |
| import android.widget.ImageView; |
| import android.widget.SectionIndexer; |
| import android.widget.TextView; |
| import android.widget.Toast; |
| |
| public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAdapter, SectionIndexer { |
| |
| private ExecutorService infos_fetcher = Executors.newCachedThreadPool(); |
| Context mContext; |
| |
| private ArrayList<CallContact> mContacts; |
| private int[] mSectionIndices; |
| private Character[] mSectionLetters; |
| WeakReference<ContactListFragment> parent; |
| private LayoutInflater mInflater; |
| |
| // private static final String TAG = ContactsAdapter.class.getSimpleName(); |
| |
| public ContactsAdapter(ContactListFragment contactListFragment) { |
| super(); |
| mContext = contactListFragment.getActivity(); |
| mInflater = LayoutInflater.from(mContext); |
| parent = new WeakReference<ContactListFragment>(contactListFragment); |
| mContacts = new ArrayList<CallContact>(); |
| mSectionIndices = getSectionIndices(); |
| mSectionLetters = getSectionLetters(); |
| } |
| |
| public static final int TYPE_HEADER = 0; |
| public static final int TYPE_CONTACT = 1; |
| |
| private int[] getSectionIndices() { |
| ArrayList<Integer> sectionIndices = new ArrayList<Integer>(); |
| if (mContacts.isEmpty()) |
| return new int[0]; |
| char lastFirstChar = mContacts.get(0).getmDisplayName().charAt(0); |
| sectionIndices.add(0); |
| for (int i = 1; i < mContacts.size(); i++) { |
| if (mContacts.get(i).getmDisplayName().charAt(0) != lastFirstChar) { |
| lastFirstChar = mContacts.get(i).getmDisplayName().charAt(0); |
| sectionIndices.add(i); |
| } |
| } |
| int[] sections = new int[sectionIndices.size()]; |
| for (int i = 0; i < sectionIndices.size(); i++) { |
| sections[i] = sectionIndices.get(i); |
| } |
| return sections; |
| } |
| |
| private Character[] getSectionLetters() { |
| Character[] letters = new Character[mSectionIndices.length]; |
| for (int i = 0; i < mSectionIndices.length; i++) { |
| letters[i] = mContacts.get(mSectionIndices[i]).getmDisplayName().charAt(0); |
| } |
| return letters; |
| } |
| |
| @Override |
| public View getView(int position, View convertView, ViewGroup root) { |
| ContactView entryView; |
| |
| if (convertView == null) { |
| convertView = mInflater.inflate(R.layout.item_contact, null); |
| |
| entryView = new ContactView(); |
| entryView.quick_starred = (ImageButton) convertView.findViewById(R.id.quick_starred); |
| entryView.quick_edit = (ImageButton) convertView.findViewById(R.id.quick_edit); |
| entryView.quick_discard = (ImageButton) convertView.findViewById(R.id.quick_discard); |
| entryView.quick_call = (ImageButton) convertView.findViewById(R.id.quick_call); |
| entryView.quick_msg = (ImageButton) convertView.findViewById(R.id.quick_message); |
| entryView.photo = (ImageView) convertView.findViewById(R.id.photo); |
| entryView.display_name = (TextView) convertView.findViewById(R.id.display_name); |
| convertView.setTag(entryView); |
| } else { |
| entryView = (ContactView) convertView.getTag(); |
| } |
| |
| final CallContact item = mContacts.get(position); |
| |
| entryView.display_name.setText(item.getmDisplayName()); |
| |
| if (item.hasPhoto()) { |
| entryView.photo.setImageBitmap(item.getPhoto()); |
| } else { |
| infos_fetcher.execute(new ContactPictureTask(mContext, entryView.photo, item)); |
| } |
| |
| entryView.quick_call.setOnClickListener(new OnClickListener() { |
| |
| @Override |
| public void onClick(View v) { |
| parent.get().mCallbacks.onCallContact(item); |
| |
| } |
| }); |
| |
| entryView.quick_msg.setOnClickListener(new OnClickListener() { |
| |
| @Override |
| public void onClick(View v) { |
| parent.get().mCallbacks.onTextContact(item); |
| } |
| }); |
| |
| entryView.quick_starred.setOnClickListener(new OnClickListener() { |
| |
| @Override |
| public void onClick(View v) { |
| Toast.makeText(mContext, "Coming soon", Toast.LENGTH_SHORT).show(); |
| } |
| }); |
| |
| entryView.quick_edit.setOnClickListener(new OnClickListener() { |
| |
| @Override |
| public void onClick(View v) { |
| parent.get().mCallbacks.onEditContact(item); |
| |
| } |
| }); |
| |
| entryView.quick_discard.setOnClickListener(new OnClickListener() { |
| |
| @Override |
| public void onClick(View v) { |
| Toast.makeText(mContext, "Coming soon", Toast.LENGTH_SHORT).show(); |
| |
| } |
| }); |
| |
| entryView.quick_edit.setClickable(false); |
| entryView.quick_discard.setClickable(false); |
| entryView.quick_starred.setClickable(false); |
| |
| return convertView; |
| } |
| |
| /********************* |
| * ViewHolder Pattern |
| *********************/ |
| public class ContactView { |
| ImageButton quick_starred, quick_edit, quick_discard, quick_call, quick_msg; |
| ImageView photo; |
| TextView display_name; |
| } |
| |
| @Override |
| public int getCount() { |
| return mContacts.size(); |
| } |
| |
| @Override |
| public int getViewTypeCount() { |
| return 2; |
| } |
| |
| @Override |
| public long getItemId(int position) { |
| return 0; |
| } |
| |
| @Override |
| public View getHeaderView(int position, View convertView, ViewGroup parent) { |
| HeaderViewHolder holder; |
| |
| if (convertView == null) { |
| holder = new HeaderViewHolder(); |
| convertView = mInflater.inflate(R.layout.header, parent, false); |
| holder.text = (TextView) convertView.findViewById(R.id.header_letter); |
| convertView.setTag(holder); |
| } else { |
| holder = (HeaderViewHolder) convertView.getTag(); |
| } |
| |
| // set header text as first char in name |
| char headerChar = mContacts.get(position).getmDisplayName().subSequence(0, 1).charAt(0); |
| |
| holder.text.setText("" + headerChar); |
| |
| return convertView; |
| |
| } |
| |
| class HeaderViewHolder { |
| TextView text; |
| } |
| |
| @Override |
| public long getHeaderId(int position) { |
| // return the first character of the name as ID because this is what |
| // headers are based upon |
| return mContacts.get(position).getmDisplayName().subSequence(0, 1).charAt(0); |
| } |
| |
| @Override |
| public int getPositionForSection(int section) { |
| if (section >= mSectionIndices.length) { |
| section = mSectionIndices.length - 1; |
| } else if (section < 0) { |
| section = 0; |
| } |
| return mSectionIndices[section]; |
| } |
| |
| @Override |
| public int getSectionForPosition(int position) { |
| for (int i = 0; i < mSectionIndices.length; i++) { |
| if (position < mSectionIndices[i]) { |
| return i - 1; |
| } |
| } |
| return mSectionIndices.length - 1; |
| } |
| |
| @Override |
| public Object[] getSections() { |
| return mSectionLetters; |
| } |
| |
| @Override |
| public CallContact getItem(int position) { |
| return mContacts.get(position); |
| } |
| |
| public void clear() { |
| mContacts = new ArrayList<CallContact>(); |
| mSectionIndices = new int[0]; |
| mSectionLetters = new Character[0]; |
| notifyDataSetChanged(); |
| } |
| |
| public void restore() { |
| mContacts = new ArrayList<CallContact>(); |
| mSectionIndices = getSectionIndices(); |
| mSectionLetters = getSectionLetters(); |
| notifyDataSetChanged(); |
| } |
| |
| public void addAll(ArrayList<CallContact> tmp) { |
| mContacts.addAll(tmp); |
| mSectionIndices = getSectionIndices(); |
| mSectionLetters = getSectionLetters(); |
| notifyDataSetChanged(); |
| } |
| |
| } |