• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.contacts.group;
18 
19 import com.android.contacts.ContactPhotoManager;
20 import com.android.contacts.GroupListLoader;
21 import com.android.contacts.R;
22 import com.android.contacts.model.AccountType;
23 import com.android.contacts.model.AccountTypeManager;
24 import com.android.internal.util.Objects;
25 
26 import android.content.ContentUris;
27 import android.content.Context;
28 import android.database.Cursor;
29 import android.net.Uri;
30 import android.provider.ContactsContract.Groups;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.ViewGroup;
34 import android.widget.BaseAdapter;
35 import android.widget.TextView;
36 
37 /**
38  * Adapter to populate the list of groups.
39  */
40 public class GroupBrowseListAdapter extends BaseAdapter {
41 
42     private final Context mContext;
43     private final LayoutInflater mLayoutInflater;
44     private final AccountTypeManager mAccountTypeManager;
45 
46     private Cursor mCursor;
47 
48     private boolean mSelectionVisible;
49     private Uri mSelectedGroupUri;
50 
GroupBrowseListAdapter(Context context)51     public GroupBrowseListAdapter(Context context) {
52         mContext = context;
53         mLayoutInflater = LayoutInflater.from(context);
54         mAccountTypeManager = AccountTypeManager.getInstance(mContext);
55     }
56 
setCursor(Cursor cursor)57     public void setCursor(Cursor cursor) {
58         mCursor = cursor;
59 
60         // If there's no selected group already and the cursor is valid, then by default, select the
61         // first group
62         if (mSelectedGroupUri == null && cursor != null && cursor.getCount() > 0) {
63             GroupListItem firstItem = getItem(0);
64             long groupId = (firstItem == null) ? null : firstItem.getGroupId();
65             mSelectedGroupUri = getGroupUriFromId(groupId);
66         }
67 
68         notifyDataSetChanged();
69     }
70 
getSelectedGroupPosition()71     public int getSelectedGroupPosition() {
72         if (mSelectedGroupUri == null || mCursor == null || mCursor.getCount() == 0) {
73             return -1;
74         }
75 
76         int index = 0;
77         mCursor.moveToPosition(-1);
78         while (mCursor.moveToNext()) {
79             long groupId = mCursor.getLong(GroupListLoader.GROUP_ID);
80             Uri uri = getGroupUriFromId(groupId);
81             if (mSelectedGroupUri.equals(uri)) {
82                   return index;
83             }
84             index++;
85         }
86         return -1;
87     }
88 
setSelectionVisible(boolean flag)89     public void setSelectionVisible(boolean flag) {
90         mSelectionVisible = flag;
91     }
92 
setSelectedGroup(Uri groupUri)93     public void setSelectedGroup(Uri groupUri) {
94         mSelectedGroupUri = groupUri;
95     }
96 
isSelectedGroup(Uri groupUri)97     private boolean isSelectedGroup(Uri groupUri) {
98         return mSelectedGroupUri != null && mSelectedGroupUri.equals(groupUri);
99     }
100 
getSelectedGroup()101     public Uri getSelectedGroup() {
102         return mSelectedGroupUri;
103     }
104 
105     @Override
getCount()106     public int getCount() {
107         return mCursor == null ? 0 : mCursor.getCount();
108     }
109 
110     @Override
getItemId(int position)111     public long getItemId(int position) {
112         return position;
113     }
114 
115     @Override
getItem(int position)116     public GroupListItem getItem(int position) {
117         if (mCursor == null || mCursor.isClosed() || !mCursor.moveToPosition(position)) {
118             return null;
119         }
120         String accountName = mCursor.getString(GroupListLoader.ACCOUNT_NAME);
121         String accountType = mCursor.getString(GroupListLoader.ACCOUNT_TYPE);
122         String dataSet = mCursor.getString(GroupListLoader.DATA_SET);
123         long groupId = mCursor.getLong(GroupListLoader.GROUP_ID);
124         String title = mCursor.getString(GroupListLoader.TITLE);
125         int memberCount = mCursor.getInt(GroupListLoader.MEMBER_COUNT);
126 
127         // Figure out if this is the first group for this account name / account type pair by
128         // checking the previous entry. This is to determine whether or not we need to display an
129         // account header in this item.
130         int previousIndex = position - 1;
131         boolean isFirstGroupInAccount = true;
132         if (previousIndex >= 0 && mCursor.moveToPosition(previousIndex)) {
133             String previousGroupAccountName = mCursor.getString(GroupListLoader.ACCOUNT_NAME);
134             String previousGroupAccountType = mCursor.getString(GroupListLoader.ACCOUNT_TYPE);
135             String previousGroupDataSet = mCursor.getString(GroupListLoader.DATA_SET);
136 
137             if (accountName.equals(previousGroupAccountName) &&
138                     accountType.equals(previousGroupAccountType) &&
139                     Objects.equal(dataSet, previousGroupDataSet)) {
140                 isFirstGroupInAccount = false;
141             }
142         }
143 
144         return new GroupListItem(accountName, accountType, dataSet, groupId, title,
145                 isFirstGroupInAccount, memberCount);
146     }
147 
148     @Override
getView(int position, View convertView, ViewGroup parent)149     public View getView(int position, View convertView, ViewGroup parent) {
150         GroupListItem entry = getItem(position);
151         View result;
152         GroupListItemViewCache viewCache;
153         if (convertView != null) {
154             result = convertView;
155             viewCache = (GroupListItemViewCache) result.getTag();
156         } else {
157             result = mLayoutInflater.inflate(R.layout.group_browse_list_item, parent, false);
158             viewCache = new GroupListItemViewCache(result);
159             result.setTag(viewCache);
160         }
161 
162         // Add a header if this is the first group in an account and hide the divider
163         if (entry.isFirstGroupInAccount()) {
164             bindHeaderView(entry, viewCache);
165             viewCache.accountHeader.setVisibility(View.VISIBLE);
166             viewCache.divider.setVisibility(View.GONE);
167             if (position == 0) {
168                 // Have the list's top padding in the first header.
169                 //
170                 // This allows the ListView to show correct fading effect on top.
171                 // If we have topPadding in the ListView itself, an inappropriate padding is
172                 // inserted between fading items and the top edge.
173                 viewCache.accountHeaderExtraTopPadding.setVisibility(View.VISIBLE);
174             } else {
175                 viewCache.accountHeaderExtraTopPadding.setVisibility(View.GONE);
176             }
177         } else {
178             viewCache.accountHeader.setVisibility(View.GONE);
179             viewCache.divider.setVisibility(View.VISIBLE);
180             viewCache.accountHeaderExtraTopPadding.setVisibility(View.GONE);
181         }
182 
183         // Bind the group data
184         Uri groupUri = getGroupUriFromId(entry.getGroupId());
185         String memberCountString = mContext.getResources().getQuantityString(
186                 R.plurals.group_list_num_contacts_in_group, entry.getMemberCount(),
187                 entry.getMemberCount());
188         viewCache.setUri(groupUri);
189         viewCache.groupTitle.setText(entry.getTitle());
190         viewCache.groupMemberCount.setText(memberCountString);
191 
192         if (mSelectionVisible) {
193             result.setActivated(isSelectedGroup(groupUri));
194         }
195         return result;
196     }
197 
bindHeaderView(GroupListItem entry, GroupListItemViewCache viewCache)198     private void bindHeaderView(GroupListItem entry, GroupListItemViewCache viewCache) {
199         AccountType accountType = mAccountTypeManager.getAccountType(
200                 entry.getAccountType(), entry.getDataSet());
201         viewCache.accountType.setText(accountType.getDisplayLabel(mContext).toString());
202         viewCache.accountName.setText(entry.getAccountName());
203     }
204 
getGroupUriFromId(long groupId)205     private static Uri getGroupUriFromId(long groupId) {
206         return ContentUris.withAppendedId(Groups.CONTENT_URI, groupId);
207     }
208 
209     /**
210      * Cache of the children views of a contact detail entry represented by a
211      * {@link GroupListItem}
212      */
213     public static class GroupListItemViewCache {
214         public final TextView accountType;
215         public final TextView accountName;
216         public final TextView groupTitle;
217         public final TextView groupMemberCount;
218         public final View accountHeader;
219         public final View accountHeaderExtraTopPadding;
220         public final View divider;
221         private Uri mUri;
222 
GroupListItemViewCache(View view)223         public GroupListItemViewCache(View view) {
224             accountType = (TextView) view.findViewById(R.id.account_type);
225             accountName = (TextView) view.findViewById(R.id.account_name);
226             groupTitle = (TextView) view.findViewById(R.id.label);
227             groupMemberCount = (TextView) view.findViewById(R.id.count);
228             accountHeader = view.findViewById(R.id.group_list_header);
229             accountHeaderExtraTopPadding = view.findViewById(R.id.header_extra_top_padding);
230             divider = view.findViewById(R.id.divider);
231         }
232 
setUri(Uri uri)233         public void setUri(Uri uri) {
234             mUri = uri;
235         }
236 
getUri()237         public Uri getUri() {
238             return mUri;
239         }
240     }
241 }