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