ContactListAdapter.java :  » App » android-chatty » ru » chatty » app » Android Open Source

Android Open Source » App » android chatty 
android chatty » ru » chatty » app » ContactListAdapter.java
/* ContactListAdapter.java
 *
 * Copyright 2011 Aleksey Konovalov
 * All Rights Reserved.
 *
 * 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 2 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, see <http://www.gnu.org/licenses/>. 
 * 
 */

package ru.chatty.app;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

import ru.chatty.engine.AccountsManager;
import ru.chatty.im.Account;
import ru.chatty.im.Contact;
import ru.chatty.im.ContactListListener;
import ru.chatty.im.MessagesListener;
import ru.chatty.im.ProtocolFeatures;
import ru.chatty.service.ChattyService;
import ru.chatty.service.Preferences;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class ContactListAdapter extends BaseExpandableListAdapter implements
    ContactListListener, MessagesListener, OnSharedPreferenceChangeListener {

  private static final String LOG_TAG = "Chatty:ContactListAdapter";

  //     
  private HashMap<String, Integer> groupsIndex = new HashMap<String, Integer>();
  //  ,     .    
  //  ,       ,  
  //   
  private HashMap<Contact, Integer> contactsIndex = new HashMap<Contact, Integer>();
  //  
  private List<Group> groups = new ArrayList<Group>();

  private LayoutInflater inflater;
  private final AlphaAnimation unreadMessageAnim;
  // private final Activity activity;
  private AccountsManager accountsManager = null;
  private SharedPreferences preferences;
  private volatile boolean hideOfflineContacts;
  private final Activity mActivity;

  Comparator<Contact> contactsComparator = new Comparator<Contact>() {
    @Override
    public int compare(Contact c1, Contact c2) {
      if (c1.unreadMessages())
        return c2.unreadMessages() ? 0 : -1;
      if (c2.unreadMessages())
        return 1;
      Boolean c1Online = c1.getMainStatus() != Contact.MAIN_STATUS_OFFLINE;
      Boolean c2Online = c2.getMainStatus() != Contact.MAIN_STATUS_OFFLINE;
      return c2Online.compareTo(c1Online);
    }
  };

  private final class Group {
    public String groupName;
    public List<Contact> contacts = new ArrayList<Contact>();
    public int onlineCount = 0;

    public Group(String name) {
      groupName = name;
    }
  }

  public ContactListAdapter(Activity activity) {
    // this.activity = activity;
    inflater = LayoutInflater.from(activity);

    mActivity = activity;

    preferences = PreferenceManager.getDefaultSharedPreferences(activity);
    preferences.registerOnSharedPreferenceChangeListener(this);
    hideOfflineContacts = preferences.getBoolean(
        Preferences.PREF_HIDE_OFFLINE_CONTACTS, false);

    unreadMessageAnim = new AlphaAnimation(1.0f, 0.6f);
    unreadMessageAnim.setRepeatCount(Animation.INFINITE);
    unreadMessageAnim.setRepeatMode(Animation.REVERSE);
    unreadMessageAnim.setDuration(300);
    unreadMessageAnim.start();

    final ChattyApplication app = ChattyApplication
        .getApplication(activity);
    app.callWhenServiceConnected(new Runnable() {

      @Override
      public void run() {
        ChattyService service = app.getService();
        if (service != null) {
          accountsManager = service.getAccountsManager();
          accountsManager
              .registerContactListListener(ContactListAdapter.this);
          accountsManager
              .registerMessagesListener(ContactListAdapter.this);
          notifyDataSetChanged();
        } else
          Log.e(LOG_TAG, "Service loaded, but equals null");
      }
    });
  }

  private synchronized int getGroupIndexByName(String groupName) {
    Integer groupId = groupsIndex.get(groupName);
    if (groupId != null)
      return groupId;
    groups.add(new Group(groupName));
    int pos = groups.size() - 1;
    groupsIndex.put(groupName, pos);
    return pos;
  }

  private void sortContacts(List<Contact> contacts) {
    Collections.sort(contacts, contactsComparator);
  }

  public final void uninitialize() {
    if (accountsManager != null)
      accountsManager.unregisterContactListListener(this);
    preferences.unregisterOnSharedPreferenceChangeListener(this);
  }

  /*
   * public static View getItemViewIfVisible(AdapterView<?> holder, int
   * itemPos) { int firstPosition = holder.getFirstVisiblePosition(); int
   * wantedChild = itemPos - firstPosition; if (wantedChild < 0 || wantedChild
   * >= holder.getChildCount()) return null; return
   * holder.getChildAt(wantedChild); }
   * 
   * public static void invalidateByPos(AdapterView<?> parent, int position) {
   * final View itemView = getItemViewIfVisible(parent, position); if
   * (itemView != null) itemView.invalidate(); }
   */
  public final void update() {
    mActivity.runOnUiThread(new Runnable() {
      @Override
      public void run() {
        notifyDataSetInvalidated();
      }
    });
  }

  @Override
  public synchronized Contact getChild(int groupPosition, int childPosition) {
    return groups.get(groupPosition).contacts.get(childPosition);
  }

  @Override
  public long getChildId(int groupPosition, int childPosition) {
    return childPosition;
  }

  @Override
  public View getChildView(int groupPosition, int childPosition,
      boolean isLastChild, View convertView, ViewGroup parent) {
    if (convertView == null)
      convertView = inflater.inflate(R.layout.contact_list_item, null);

    Contact contact;
    synchronized (this) {
      Group g = groups.get(groupPosition);
      if (g == null) {
        Log.w(LOG_TAG, "getChildView: group not found");
        return convertView;
      }
      contact = g.contacts.get(childPosition);
    }

    ProtocolFeatures features = contact.getAccount().getProtocolFeatures();

    TextView contactName = (TextView) convertView
        .findViewById(R.id.ContactName);
    contactName.setText(contact.getNick());

    ImageView statusImage = (ImageView) convertView
        .findViewById(R.id.StatusImage);

    int statusPictId = features.getMainStatusPictureId(contact
        .getMainStatus());

    statusImage.setImageResource(statusPictId);

    statusImage.setAnimation(contact.unreadMessages() ? unreadMessageAnim
        : null);

    Contact.AdditionalStatus additionalStatus = contact
        .getAdditionalStatus();
    ImageView additionalStatusImage = (ImageView) convertView
        .findViewById(R.id.AdditionalStatusImage);
    int additionalStatusResId = features
        .getAdditionalStatusPictureId(additionalStatus.status);
    additionalStatusImage.setImageResource(additionalStatusResId);
    String statusText = "";
    if (!TextUtils.isEmpty(additionalStatus.title))
      statusText = additionalStatus.title + ' ';
    if (!TextUtils.isEmpty(additionalStatus.description))
      statusText += additionalStatus.description;
    TextView additionalStatusText = (TextView) convertView
        .findViewById(R.id.AdditionalStatusText);
    if (!TextUtils.isEmpty(statusText)) {
      additionalStatusText.setText(statusText);
      additionalStatusText.setVisibility(TextView.VISIBLE);
    } else
      additionalStatusText.setVisibility(TextView.INVISIBLE);

    return convertView;
  }

  @Override
  public synchronized int getChildrenCount(int groupPosition) {
    Group group = groups.get(groupPosition);
    return hideOfflineContacts ? group.onlineCount : group.contacts.size();
  }

  @Override
  public synchronized Group getGroup(int groupPosition) {
    return groups.get(groupPosition);
  }

  @Override
  public synchronized int getGroupCount() {
    return groups.size();
  }

  @Override
  public long getGroupId(int groupPosition) {
    return groupPosition;
  }

  @Override
  public View getGroupView(int groupPosition, boolean isExpanded,
      View convertView, ViewGroup parent) {
    if (convertView == null) {
      convertView = inflater.inflate(R.layout.contact_list_group, null);
    }
    TextView groupNameView = (TextView) convertView
        .findViewById(R.id.GroupName);
    TextView groupStatView = (TextView) convertView
        .findViewById(R.id.GroupStat);

    String groupName;
    String groupStat;
    synchronized (this) {
      Group group = getGroup(groupPosition);
      groupName = group.groupName;
      groupStat = group.onlineCount + "/" + group.contacts.size();
    }
    groupNameView.setText(groupName);
    groupStatView.setText(groupStat);

    return convertView;
  }

  @Override
  public boolean hasStableIds() {
    return true;
  }

  @Override
  public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
  }

  // ContactListListener

  @Override
  public void onAddUser(Account account, Contact user) {
    synchronized (this) {
      int groupIndex = getGroupIndexByName(user.getGroupName());
      Group group = groups.get(groupIndex);
      List<Contact> contacts = group.contacts;
      if (user.getMainStatus() != Contact.MAIN_STATUS_OFFLINE)
        ++group.onlineCount;
      contacts.add(user);
      contactsIndex.put(user, groupIndex);
      sortContacts(contacts);
    }
    update();
  }

  @Override
  public void onDeleteUser(Account account, Contact user) {
    // TODO Auto-generated method stub
  }

  @Override
  public final void onStatusChanged(Account account, Contact user, int oldStatus) {
    boolean oldStatusIsOffline = oldStatus == Contact.MAIN_STATUS_OFFLINE;
    boolean newStatusIsOffline = user.getMainStatus() == Contact.MAIN_STATUS_OFFLINE;
    if (oldStatusIsOffline != newStatusIsOffline) {
      synchronized (this) {
        Integer groupIndex = contactsIndex.get(user);
        if (groupIndex != null) {
          Group group = groups.get(groupIndex);
          sortContacts(group.contacts);
          if (oldStatusIsOffline)
            ++group.onlineCount;
          else
            --group.onlineCount;
        }
      }
    }
    if (oldStatus != user.getMainStatus())
      update();
  }
  
  @Override
  public final void onAdditionalStatusChanged(Account account, Contact user) {
    update();
  }

  @Override
  public void onChangeUserInfo(Account account, Contact user) {
    // TODO Auto-generated method stub
  }

  @Override
  public void onUpdateContactList(Account account, List<Contact> contactList) {
    synchronized (this) {
      for (Contact contact : contactList) {
        //  ,    
        Integer oldGroupIndex = contactsIndex.get(contact);
        if (oldGroupIndex != null) {
          Group oldGroup = groups.get(oldGroupIndex);
          oldGroup.contacts.remove(contact);
          contactsIndex.remove(contact);
        }

        int groupIndex = getGroupIndexByName(contact.getGroupName());
        Group group = groups.get(groupIndex);
        group.contacts.add(contact);
        if (contact.getMainStatus() != Contact.MAIN_STATUS_OFFLINE)
          ++group.onlineCount;
        contactsIndex.put(contact, groupIndex);
      }
      for (Group group : groups)
        sortContacts(group.contacts);
    }
    update();
  }

  // MessagesListener

  @Override
  public synchronized void onMessage(String accountID, String message,
      Contact contact) {
    Integer groupIndex = contactsIndex.get(contact);
    if (groupIndex != null) {
      List<Contact> contacts = groups.get(groupIndex).contacts;
      sortContacts(contacts);
      update();
    }
  }

  @Override
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    if (key.equals(Preferences.PREF_HIDE_OFFLINE_CONTACTS)) {
      hideOfflineContacts = prefs.getBoolean(key, false);
      update();
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.