📄 contactlisttreeadapter.java
字号:
/* * Copyright (C) 2008 Esmertec AG. * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.android.im.app;import android.app.Activity;import android.content.AsyncQueryHandler;import android.content.ContentQueryMap;import android.content.ContentResolver;import android.content.ContentUris;import android.content.ContentValues;import android.content.Context;import android.content.res.Resources;import android.database.ContentObserver;import android.database.Cursor;import android.database.DataSetObserver;import android.net.Uri;import android.os.RemoteException;import android.provider.Im;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseExpandableListAdapter;import android.widget.CursorTreeAdapter;import android.widget.TextView;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import com.android.im.IImConnection;import com.android.im.R;import com.android.im.plugin.BrandingResourceIDs;import java.util.ArrayList;import java.util.Observable;import java.util.Observer;public class ContactListTreeAdapter extends BaseExpandableListAdapter implements AbsListView.OnScrollListener{ private static final String[] CONTACT_LIST_PROJECTION = { Im.ContactList._ID, Im.ContactList.NAME, }; private static final int COLUMN_CONTACT_LIST_ID = 0; private static final int COLUMN_CONTACT_LIST_NAME = 1; Activity mActivity; SimpleAlertHandler mHandler; private LayoutInflater mInflate; private long mProviderId; long mAccountId; Cursor mOngoingConversations; Cursor mSubscriptions; boolean mDataValid; ListTreeAdapter mAdapter; private boolean mHideOfflineContacts; final MyContentObserver mContentObserver; final MyDataSetObserver mDataSetObserver; private ArrayList<Integer> mExpandedGroups; private static final int TOKEN_CONTACT_LISTS = -1; private static final int TOKEN_ONGOING_CONVERSATION = -2; private static final int TOKEN_SUBSCRITPTION = -3; private static final String NON_CHAT_AND_BLOCKED_CONTACTS = "(" + Im.Contacts.LAST_MESSAGE_DATE + " IS NULL) AND (" + Im.Contacts.TYPE + "!=" + Im.Contacts.TYPE_BLOCKED + ")"; private static final String CONTACTS_SELECTION = Im.Contacts.CONTACTLIST + "=? AND " + NON_CHAT_AND_BLOCKED_CONTACTS; private static final String ONLINE_CONTACT_SELECTION = CONTACTS_SELECTION + " AND "+ Im.Contacts.PRESENCE_STATUS + " != " + Im.Presence.OFFLINE; static final void log(String msg) { Log.d(ImApp.LOG_TAG, "<ContactListAdapter>" + msg); } static final String[] CONTACT_COUNT_PROJECTION = { Im.Contacts.CONTACTLIST, Im.Contacts._COUNT, }; ContentQueryMap mOnlineContactsCountMap; // Async QueryHandler private final class QueryHandler extends AsyncQueryHandler { public QueryHandler(Context context) { super(context.getContentResolver()); } @Override protected void onQueryComplete(int token, Object cookie, Cursor c) { if(Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){ log("onQueryComplete:token=" + token); } if (token == TOKEN_CONTACT_LISTS) { mDataValid = true; mAdapter.setGroupCursor(c); } else if (token == TOKEN_ONGOING_CONVERSATION) { setOngoingConversations(c); notifyDataSetChanged(); } else if (token == TOKEN_SUBSCRITPTION) { setSubscriptions(c); notifyDataSetChanged(); } else { int count = mAdapter.getGroupCount(); for (int pos = 0; pos < count; pos++) { long listId = mAdapter.getGroupId(pos); if (listId == token) { mAdapter.setChildrenCursor(pos, c); break; } } } } } private QueryHandler mQueryHandler; private int mScrollState; private boolean mAutoRequery; private boolean mRequeryPending; public ContactListTreeAdapter(IImConnection conn, Activity activity) { mActivity = activity; mInflate = activity.getLayoutInflater(); mHandler = new SimpleAlertHandler(activity); mAdapter = new ListTreeAdapter(null); mContentObserver = new MyContentObserver(); mDataSetObserver = new MyDataSetObserver(); mExpandedGroups = new ArrayList<Integer>(); mQueryHandler = new QueryHandler(activity); changeConnection(conn); } public void changeConnection(IImConnection conn) { mQueryHandler.cancelOperation(TOKEN_ONGOING_CONVERSATION); mQueryHandler.cancelOperation(TOKEN_SUBSCRITPTION); mQueryHandler.cancelOperation(TOKEN_CONTACT_LISTS); synchronized (this) { if (mOngoingConversations != null) { mOngoingConversations.close(); mOngoingConversations = null; } if (mSubscriptions != null) { mSubscriptions.close(); mSubscriptions = null; } if (mOnlineContactsCountMap != null) { mOnlineContactsCountMap.close(); } } mAdapter.notifyDataSetChanged(); if (conn != null) { try { mProviderId = conn.getProviderId(); mAccountId = conn.getAccountId(); startQueryOngoingConversations(); startQueryContactLists(); startQuerySubscriptions(); } catch (RemoteException e) { // Service died! } } } public void setHideOfflineContacts(boolean hide) { if (mHideOfflineContacts != hide) { mHideOfflineContacts = hide; mAdapter.notifyDataSetChanged(); } } public void startAutoRequery() { if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){ log("startAutoRequery()"); } mAutoRequery = true; if (mRequeryPending) { mRequeryPending = false; startQueryOngoingConversations(); } } private void startQueryContactLists() { if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){ log("startQueryContactLists()"); } Uri uri = Im.ContactList.CONTENT_URI; uri = ContentUris.withAppendedId(uri, mProviderId); uri = ContentUris.withAppendedId(uri, mAccountId); mQueryHandler.startQuery(TOKEN_CONTACT_LISTS, null, uri, CONTACT_LIST_PROJECTION, null, null, Im.ContactList.DEFAULT_SORT_ORDER); } void startQueryOngoingConversations() { if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){ log("startQueryOngoingConversations()"); } Uri uri = Im.Contacts.CONTENT_URI_CHAT_CONTACTS_BY; uri = ContentUris.withAppendedId(uri, mProviderId); uri = ContentUris.withAppendedId(uri, mAccountId); mQueryHandler.startQuery(TOKEN_ONGOING_CONVERSATION, null, uri, ContactView.CONTACT_PROJECTION, null, null, Im.Contacts.DEFAULT_SORT_ORDER); } void startQuerySubscriptions() { if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){ log("startQuerySubscriptions()"); } Uri uri = Im.Contacts.CONTENT_URI_CONTACTS_BY; uri = ContentUris.withAppendedId(uri, mProviderId); uri = ContentUris.withAppendedId(uri, mAccountId); mQueryHandler.startQuery(TOKEN_SUBSCRITPTION, null, uri, ContactView.CONTACT_PROJECTION, String.format("%s=%d AND %s=%d", Im.Contacts.SUBSCRIPTION_STATUS, Im.Contacts.SUBSCRIPTION_STATUS_SUBSCRIBE_PENDING, Im.Contacts.SUBSCRIPTION_TYPE, Im.Contacts.SUBSCRIPTION_TYPE_FROM), null,Im.Contacts.DEFAULT_SORT_ORDER); } void startQueryContacts(long listId) { if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){ log("startQueryContacts - listId=" + listId); } String selection = mHideOfflineContacts ? ONLINE_CONTACT_SELECTION : CONTACTS_SELECTION; String[] args = { Long.toString(listId) }; int token = (int)listId; mQueryHandler.startQuery(token, null, Im.Contacts.CONTENT_URI, ContactView.CONTACT_PROJECTION, selection, args, Im.Contacts.DEFAULT_SORT_ORDER); } public Object getChild(int groupPosition, int childPosition) { if (isPosForOngoingConversation(groupPosition)) { // No cursor exists for the "Empty" TextView item if (getOngoingConversationCount() == 0) return null; return moveTo(getOngoingConversations(), childPosition); } else if (isPosForSubscription(groupPosition)) { return moveTo(getSubscriptions(), childPosition); } else { return mAdapter.getChild(getChildAdapterPosition(groupPosition), childPosition); } } public long getChildId(int groupPosition, int childPosition) { if (isPosForOngoingConversation(groupPosition)) { // No cursor id exists for the "Empty" TextView item if (getOngoingConversationCount() == 0) return 0; return getId(getOngoingConversations(), childPosition); } else if (isPosForSubscription(groupPosition)) { return getId(getSubscriptions(), childPosition); } else { return mAdapter.getChildId(getChildAdapterPosition(groupPosition), childPosition); } } public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { boolean isOngoingConversation = isPosForOngoingConversation(groupPosition); boolean displayEmpty = isOngoingConversation && (getOngoingConversationCount() == 0); if (isOngoingConversation || isPosForSubscription(groupPosition)) { View view = null; if (convertView != null) { // use the convert view if it matches the type required by displayEmpty if (displayEmpty && (convertView instanceof TextView)) { view = convertView; ((TextView) view).setText(mActivity.getText(R.string.empty_conversation_group)); } else if (!displayEmpty && (convertView instanceof ContactView)) { view = convertView; } } if (view == null) { if (displayEmpty) { view = newEmptyView(parent); } else { view = newChildView(parent); } } if (!displayEmpty) { Cursor cursor = isPosForOngoingConversation(groupPosition) ? getOngoingConversations() : getSubscriptions(); cursor.moveToPosition(childPosition); ((ContactView) view).bind(cursor, null, isScrolling()); } return view; } else { return mAdapter.getChildView(getChildAdapterPosition(groupPosition), childPosition, isLastChild, convertView, parent); } } public int getChildrenCount(int groupPosition) { if (!mDataValid) { return 0; } if (isPosForOngoingConversation(groupPosition)) { // if there are no ongoing conversations, we want to display "empty" textview int count = getOngoingConversationCount(); if (count == 0) { count = 1; } return count; } else if (isPosForSubscription(groupPosition)) { return getSubscriptionCount(); } else { // XXX getChildrenCount() may be called with an invalid groupPosition that is larger // than the total number of all groups. int position = getChildAdapterPosition(groupPosition); if (position >= mAdapter.getGroupCount()) { Log.w(ImApp.LOG_TAG, "getChildrenCount out of range"); return 0; } return mAdapter.getChildrenCount(position); } } public Object getGroup(int groupPosition) { if (isPosForOngoingConversation(groupPosition) || isPosForSubscription(groupPosition)) { return null; } else { return mAdapter.getGroup(getChildAdapterPosition(groupPosition)); } } public int getGroupCount() { if (!mDataValid) { return 0; } int count = mAdapter.getGroupCount(); // ongoing conversations count++; if (getSubscriptionCount() > 0) { count++; } return count; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -