/* * Copyright (C) 2011 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.contacts.group; import com.android.contacts.ContactPhotoManager; import com.android.contacts.GroupListLoader; import com.android.contacts.R; import com.android.contacts.model.AccountType; import com.android.contacts.model.AccountTypeManager; import com.android.internal.util.Objects; import android.content.ContentUris; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract.Groups; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; /** * Adapter to populate the list of groups. */ public class GroupBrowseListAdapter extends BaseAdapter { private final Context mContext; private final LayoutInflater mLayoutInflater; private final AccountTypeManager mAccountTypeManager; private Cursor mCursor; private boolean mSelectionVisible; private Uri mSelectedGroupUri; public GroupBrowseListAdapter(Context context) { mContext = context; mLayoutInflater = LayoutInflater.from(context); mAccountTypeManager = AccountTypeManager.getInstance(mContext); } public void setCursor(Cursor cursor) { mCursor = cursor; // If there's no selected group already and the cursor is valid, then by default, select the // first group if (mSelectedGroupUri == null && cursor != null && cursor.getCount() > 0) { GroupListItem firstItem = getItem(0); long groupId = (firstItem == null) ? null : firstItem.getGroupId(); mSelectedGroupUri = getGroupUriFromId(groupId); } notifyDataSetChanged(); } public int getSelectedGroupPosition() { if (mSelectedGroupUri == null || mCursor == null || mCursor.getCount() == 0) { return -1; } int index = 0; mCursor.moveToPosition(-1); while (mCursor.moveToNext()) { long groupId = mCursor.getLong(GroupListLoader.GROUP_ID); Uri uri = getGroupUriFromId(groupId); if (mSelectedGroupUri.equals(uri)) { return index; } index++; } return -1; } public void setSelectionVisible(boolean flag) { mSelectionVisible = flag; } public void setSelectedGroup(Uri groupUri) { mSelectedGroupUri = groupUri; } private boolean isSelectedGroup(Uri groupUri) { return mSelectedGroupUri != null && mSelectedGroupUri.equals(groupUri); } public Uri getSelectedGroup() { return mSelectedGroupUri; } @Override public int getCount() { return mCursor == null ? 0 : mCursor.getCount(); } @Override public long getItemId(int position) { return position; } @Override public GroupListItem getItem(int position) { if (mCursor == null || mCursor.isClosed() || !mCursor.moveToPosition(position)) { return null; } String accountName = mCursor.getString(GroupListLoader.ACCOUNT_NAME); String accountType = mCursor.getString(GroupListLoader.ACCOUNT_TYPE); String dataSet = mCursor.getString(GroupListLoader.DATA_SET); long groupId = mCursor.getLong(GroupListLoader.GROUP_ID); String title = mCursor.getString(GroupListLoader.TITLE); int memberCount = mCursor.getInt(GroupListLoader.MEMBER_COUNT); // Figure out if this is the first group for this account name / account type pair by // checking the previous entry. This is to determine whether or not we need to display an // account header in this item. int previousIndex = position - 1; boolean isFirstGroupInAccount = true; if (previousIndex >= 0 && mCursor.moveToPosition(previousIndex)) { String previousGroupAccountName = mCursor.getString(GroupListLoader.ACCOUNT_NAME); String previousGroupAccountType = mCursor.getString(GroupListLoader.ACCOUNT_TYPE); String previousGroupDataSet = mCursor.getString(GroupListLoader.DATA_SET); if (accountName.equals(previousGroupAccountName) && accountType.equals(previousGroupAccountType) && Objects.equal(dataSet, previousGroupDataSet)) { isFirstGroupInAccount = false; } } return new GroupListItem(accountName, accountType, dataSet, groupId, title, isFirstGroupInAccount, memberCount); } @Override public View getView(int position, View convertView, ViewGroup parent) { GroupListItem entry = getItem(position); View result; GroupListItemViewCache viewCache; if (convertView != null) { result = convertView; viewCache = (GroupListItemViewCache) result.getTag(); } else { result = mLayoutInflater.inflate(R.layout.group_browse_list_item, parent, false); viewCache = new GroupListItemViewCache(result); result.setTag(viewCache); } // Add a header if this is the first group in an account and hide the divider if (entry.isFirstGroupInAccount()) { bindHeaderView(entry, viewCache); viewCache.accountHeader.setVisibility(View.VISIBLE); viewCache.divider.setVisibility(View.GONE); if (position == 0) { // Have the list's top padding in the first header. // // This allows the ListView to show correct fading effect on top. // If we have topPadding in the ListView itself, an inappropriate padding is // inserted between fading items and the top edge. viewCache.accountHeaderExtraTopPadding.setVisibility(View.VISIBLE); } else { viewCache.accountHeaderExtraTopPadding.setVisibility(View.GONE); } } else { viewCache.accountHeader.setVisibility(View.GONE); viewCache.divider.setVisibility(View.VISIBLE); viewCache.accountHeaderExtraTopPadding.setVisibility(View.GONE); } // Bind the group data Uri groupUri = getGroupUriFromId(entry.getGroupId()); String memberCountString = mContext.getResources().getQuantityString( R.plurals.group_list_num_contacts_in_group, entry.getMemberCount(), entry.getMemberCount()); viewCache.setUri(groupUri); viewCache.groupTitle.setText(entry.getTitle()); viewCache.groupMemberCount.setText(memberCountString); if (mSelectionVisible) { result.setActivated(isSelectedGroup(groupUri)); } return result; } private void bindHeaderView(GroupListItem entry, GroupListItemViewCache viewCache) { AccountType accountType = mAccountTypeManager.getAccountType( entry.getAccountType(), entry.getDataSet()); viewCache.accountType.setText(accountType.getDisplayLabel(mContext).toString()); viewCache.accountName.setText(entry.getAccountName()); } private static Uri getGroupUriFromId(long groupId) { return ContentUris.withAppendedId(Groups.CONTENT_URI, groupId); } /** * Cache of the children views of a contact detail entry represented by a * {@link GroupListItem} */ public static class GroupListItemViewCache { public final TextView accountType; public final TextView accountName; public final TextView groupTitle; public final TextView groupMemberCount; public final View accountHeader; public final View accountHeaderExtraTopPadding; public final View divider; private Uri mUri; public GroupListItemViewCache(View view) { accountType = (TextView) view.findViewById(R.id.account_type); accountName = (TextView) view.findViewById(R.id.account_name); groupTitle = (TextView) view.findViewById(R.id.label); groupMemberCount = (TextView) view.findViewById(R.id.count); accountHeader = view.findViewById(R.id.group_list_header); accountHeaderExtraTopPadding = view.findViewById(R.id.header_extra_top_padding); divider = view.findViewById(R.id.divider); } public void setUri(Uri uri) { mUri = uri; } public Uri getUri() { return mUri; } } }