Group members are now displayed as ContactTiles
-For Tablet
When trying to view a list of all the group member, they
will show up as ContactTiles.
Added GroupMemberLoader as a helper class to query
for all members based on group id.
Change-Id: I7eae9066a2e881c28eca1fc157142e49a9bad725
diff --git a/res/layout/strequent_fragment.xml b/res/layout/contact_tile_list.xml
similarity index 95%
rename from res/layout/strequent_fragment.xml
rename to res/layout/contact_tile_list.xml
index 348fd0c..79c6ecf 100644
--- a/res/layout/strequent_fragment.xml
+++ b/res/layout/contact_tile_list.xml
@@ -15,7 +15,7 @@
-->
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/strequent_list"
+ android:id="@+id/contact_tile_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
diff --git a/res/layout/contact_tile_regular.xml b/res/layout/contact_tile_regular.xml
index c864ee6..c931e97 100644
--- a/res/layout/contact_tile_regular.xml
+++ b/res/layout/contact_tile_regular.xml
@@ -17,7 +17,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
class="com.android.contacts.list.ContactTileView"
android:focusable="true"
- android:padding="3dip"
+ android:padding="1dip"
android:background="@drawable/list_selector" >
<RelativeLayout
diff --git a/src/com/android/contacts/GroupMemberLoader.java b/src/com/android/contacts/GroupMemberLoader.java
new file mode 100644
index 0000000..0633bf8
--- /dev/null
+++ b/src/com/android/contacts/GroupMemberLoader.java
@@ -0,0 +1,102 @@
+/*
+ * 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;
+
+import com.android.contacts.list.ContactListAdapter;
+
+import android.content.Context;
+import android.content.CursorLoader;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Directory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Group Member loader. Loads all group members from the given groupId
+ */
+public final class GroupMemberLoader extends CursorLoader {
+
+ /**
+ * Projection map is taken from {@link ContactListAdapter}
+ */
+ private final String[] PROJECTION_DATA = new String[] {
+ // TODO: Pull Projection_data out into util class
+ Data.CONTACT_ID, // 0
+ Data.DISPLAY_NAME_PRIMARY, // 1
+ Data.DISPLAY_NAME_ALTERNATIVE, // 2
+ Data.SORT_KEY_PRIMARY, // 3
+ Data.STARRED, // 4
+ Data.CONTACT_PRESENCE, // 5
+ Data.CONTACT_CHAT_CAPABILITY, // 6
+ Data.PHOTO_ID, // 7
+ Data.PHOTO_THUMBNAIL_URI, // 8
+ Data.LOOKUP_KEY, // 9
+ Data.PHONETIC_NAME, // 10
+ Data.HAS_PHONE_NUMBER, // 11
+ };
+
+ private final long mGroupId;
+
+ public static final int CONTACT_ID_COLUMN_INDEX = 0;
+ public static final int CONTACT_DISPLAY_NAME_PRIMARY_COLUMN_INDEX = 1;
+ public static final int CONTACT_DISPLAY_NAME_ALTERNATIVE_COLUMN_INDEX = 2;
+ public static final int CONTACT_SORT_KEY_PRIMARY_COLUMN_INDEX = 3;
+ public static final int CONTACT_STARRED_COLUMN_INDEX = 4;
+ public static final int CONTACT_PRESENCE_STATUS_COLUMN_INDEX = 5;
+ public static final int CONTACT_CHAT_CAPABILITY_COLUMN_INDEX = 6;
+ public static final int CONTACT_PHOTO_ID_COLUMN_INDEX = 7;
+ public static final int CONTACT_PHOTO_URI_COLUMN_INDEX = 8;
+ public static final int CONTACT_LOOKUP_KEY_COLUMN_INDEX = 9;
+ public static final int CONTACT_PHONETIC_NAME_COLUMN_INDEX = 10;
+ public static final int CONTACT_HAS_PHONE_COLUMN_INDEX = 11;
+
+ public GroupMemberLoader(Context context, long groupId) {
+ super(context);
+ mGroupId = groupId;
+ setUri(createUri());
+ setProjection(PROJECTION_DATA);
+ setSelection(createSelection());
+ setSelectionArgs(createSelectionArgs());
+ setSortOrder(Contacts.SORT_KEY_ALTERNATIVE);
+ }
+
+ private Uri createUri() {
+ Uri uri = Data.CONTENT_URI;
+ uri = uri.buildUpon().appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
+ String.valueOf(Directory.DEFAULT)).build();
+ // TODO: Bring back dataRestriction
+ // uri = applyDataRestriction(uri);
+ return uri;
+ }
+
+ private String createSelection() {
+ StringBuilder selection = new StringBuilder();
+ selection.append(Data.MIMETYPE + "=?" + " AND " + GroupMembership.GROUP_ROW_ID + "=?");
+ return selection.toString();
+ }
+
+ private String[] createSelectionArgs() {
+ List<String> selectionArgs = new ArrayList<String>();
+ selectionArgs.add(GroupMembership.CONTENT_ITEM_TYPE);
+ selectionArgs.add(String.valueOf(mGroupId));
+ return selectionArgs.toArray(new String[0]);
+ }
+}
diff --git a/src/com/android/contacts/group/GroupDetailFragment.java b/src/com/android/contacts/group/GroupDetailFragment.java
index 8d049d5..a0b7fb5 100644
--- a/src/com/android/contacts/group/GroupDetailFragment.java
+++ b/src/com/android/contacts/group/GroupDetailFragment.java
@@ -17,14 +17,13 @@
package com.android.contacts.group;
import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.GroupMemberLoader;
import com.android.contacts.GroupMetaDataLoader;
import com.android.contacts.R;
import com.android.contacts.interactions.GroupDeletionDialogFragment;
import com.android.contacts.interactions.GroupRenamingDialogFragment;
-import com.android.contacts.list.ContactListAdapter;
-import com.android.contacts.list.ContactListFilter;
-import com.android.contacts.list.DefaultContactListAdapter;
-import com.android.contacts.util.PhoneCapabilityTester;
+import com.android.contacts.list.ContactTileAdapter;
+import com.android.contacts.list.ContactTileAdapter.DisplayType;
import android.app.Activity;
import android.app.Fragment;
@@ -36,8 +35,6 @@
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Directory;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -46,8 +43,6 @@
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
@@ -73,6 +68,7 @@
private static final int LOADER_METADATA = 0;
private static final int LOADER_MEMBERS = 1;
+ private static final int NUM_COLS = 4;
private Context mContext;
@@ -83,7 +79,7 @@
private Listener mListener;
- private ContactListAdapter mAdapter;
+ private ContactTileAdapter mAdapter;
private ContactPhotoManager mPhotoManager;
private Uri mGroupUri;
@@ -99,6 +95,8 @@
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = activity;
+ mAdapter = new ContactTileAdapter(activity, mContactTileListener, NUM_COLS,
+ DisplayType.GROUP_MEMBERS);
configurePhotoLoader();
}
@@ -115,12 +113,7 @@
mGroupTitle = (TextView) mRootView.findViewById(R.id.group_title);
mGroupSize = (TextView) mRootView.findViewById(R.id.group_size);
mMemberListView = (ListView) mRootView.findViewById(android.R.id.list);
- mMemberListView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- // TODO: Open contact detail for this person
- }
- });
+
return mRootView;
}
@@ -130,16 +123,7 @@
}
private void configureAdapter(long groupId) {
- mAdapter = new DefaultContactListAdapter(getActivity());
- mAdapter.setSectionHeaderDisplayEnabled(false);
- mAdapter.setDisplayPhotos(true);
- mAdapter.setHasHeader(0, false);
- mAdapter.setQuickContactEnabled(false);
- mAdapter.setPinnedPartitionHeadersEnabled(false);
- mAdapter.setContactNameDisplayOrder(ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY);
- mAdapter.setSortOrder(ContactsContract.Preferences.SORT_ORDER_PRIMARY);
- mAdapter.setPhotoLoader(mPhotoManager);
- mAdapter.setFilter(ContactListFilter.createGroupFilter(groupId));
+ mGroupId = groupId;
mMemberListView.setAdapter(mAdapter);
}
@@ -177,6 +161,15 @@
getLoaderManager().restartLoader(LOADER_MEMBERS, null, mGroupMemberListLoaderListener);
}
+ private final ContactTileAdapter.Listener mContactTileListener =
+ new ContactTileAdapter.Listener() {
+
+ @Override
+ public void onContactSelected(Uri contactUri) {
+ // TODO: Launch Quick Contact
+ }
+ };
+
/**
* The listener for the group metadata loader.
*/
@@ -209,15 +202,13 @@
@Override
public CursorLoader onCreateLoader(int id, Bundle args) {
- CursorLoader loader = new CursorLoader(mContext, null, null, null, null, null);
- mAdapter.configureLoader(loader, Directory.DEFAULT);
- return loader;
+ return new GroupMemberLoader(mContext, mGroupId);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
updateSize(Integer.toString(data.getCount()));
- mAdapter.changeCursor(0, data);
+ mAdapter.loadFromCursor(data);
}
@Override
diff --git a/src/com/android/contacts/list/ContactTileAdapter.java b/src/com/android/contacts/list/ContactTileAdapter.java
index 961eeb8..f3d7dae 100644
--- a/src/com/android/contacts/list/ContactTileAdapter.java
+++ b/src/com/android/contacts/list/ContactTileAdapter.java
@@ -16,8 +16,10 @@
package com.android.contacts.list;
import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.GroupMemberLoader;
import com.android.contacts.R;
import com.android.contacts.StrequentMetaDataLoader;
+
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
@@ -58,6 +60,11 @@
private int mColumnCount;
private int mDividerRowIndex;
private ContactPhotoManager mPhotoManager;
+ private int mIdIndex;
+ private int mLookupIndex;
+ private int mPhotoUriIndex;
+ private int mNameIndex;
+ private int mStarredIndex;
/**
* Configures the adapter to filter and display contacts using different view types.
@@ -85,7 +92,8 @@
/**
* Display all contacts from a group in the cursor in a
- * regular {@link ContactTileView} layout.
+ * regular {@link ContactTileView} layout. Use {@link GroupMemberLoader}
+ * when passing {@link Cursor} into loadFromCusor method.
*/
GROUP_MEMBERS
}
@@ -95,10 +103,46 @@
mListener = listener;
mContext = context;
mColumnCount = numCols;
- mPhotoManager = ContactPhotoManager.getInstance(context);
mDisplayType = displayType;
+
+ bindColumnIndices();
}
+ public void setPhotoLoader(ContactPhotoManager photoLoader) {
+ mPhotoManager = photoLoader;
+ }
+
+ /**
+ * Sets the column indices for expected {@link Cursor}
+ * based on {@link DisplayType}.
+ */
+ private void bindColumnIndices() {
+ /**
+ * Need to check for {@link DisplayType#GROUP_MEMBERS} because
+ * it has different projections than all other {@link DisplayType}s
+ * By using {@link GroupMemberLoader} and {@link StrequentMetaDataLoader}
+ * the correct {@link Cursor}s will be given.
+ */
+ if (mDisplayType == DisplayType.GROUP_MEMBERS) {
+ mIdIndex = GroupMemberLoader.CONTACT_PHOTO_ID_COLUMN_INDEX;
+ mLookupIndex = GroupMemberLoader.CONTACT_LOOKUP_KEY_COLUMN_INDEX;
+ mPhotoUriIndex = GroupMemberLoader.CONTACT_PHOTO_URI_COLUMN_INDEX;
+ mNameIndex = GroupMemberLoader.CONTACT_DISPLAY_NAME_PRIMARY_COLUMN_INDEX;
+ mStarredIndex = GroupMemberLoader.CONTACT_STARRED_COLUMN_INDEX;
+ } else {
+ mIdIndex = StrequentMetaDataLoader.CONTACT_ID;
+ mLookupIndex = StrequentMetaDataLoader.LOOKUP_KEY;
+ mPhotoUriIndex = StrequentMetaDataLoader.PHOTO_URI;
+ mNameIndex = StrequentMetaDataLoader.DISPLAY_NAME;
+ mStarredIndex = StrequentMetaDataLoader.STARRED;
+ }
+ }
+
+ /**
+ * Creates {@link ContactTileView}s for each item in {@link Cursor}.
+ * If {@link DisplayType} is {@link DisplayType#GROUP_MEMBERS} use {@link GroupMemberLoader}
+ * Else use {@link StrequentMetaDataLoader}
+ */
public void loadFromCursor(Cursor cursor) {
mContacts.clear();
mContacts2.clear();
@@ -107,19 +151,16 @@
// In that case, show an empty list of contacts.
if (cursor != null) {
while (cursor.moveToNext()) {
+ long id = cursor.getLong(mIdIndex);
+ String photoUri = cursor.getString(mPhotoUriIndex);
+ String lookupKey = cursor.getString(mLookupIndex);
+ boolean isStarred = (cursor.getInt(mStarredIndex) == 1);
+
ContactEntry contact = new ContactEntry();
-
- long id = cursor.getLong(StrequentMetaDataLoader.CONTACT_ID);
- String lookupKey = cursor.getString(StrequentMetaDataLoader.LOOKUP_KEY);
- String photoUri = cursor.getString(StrequentMetaDataLoader.PHOTO_URI);
-
+ contact.name = cursor.getString(mNameIndex);
contact.photoUri = (photoUri != null ? Uri.parse(photoUri) : null);
-
contact.lookupKey = ContentUris.withAppendedId(
Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey), id);
- contact.name = cursor.getString(StrequentMetaDataLoader.DISPLAY_NAME);
-
- boolean isStarred = (cursor.getInt(StrequentMetaDataLoader.STARRED) == 1);
switch (mDisplayType) {
case STREQUENT:
@@ -157,11 +198,6 @@
return numRows;
}
- public void setColumnCount(int colCount) {
- mColumnCount = colCount;
- notifyDataSetChanged();
- }
-
/**
* Returns the number of rows required to show the provided number of entries
* with the current number of columns.
diff --git a/src/com/android/contacts/list/StrequentContactListFragment.java b/src/com/android/contacts/list/StrequentContactListFragment.java
index d2e2ca3..d226950 100644
--- a/src/com/android/contacts/list/StrequentContactListFragment.java
+++ b/src/com/android/contacts/list/StrequentContactListFragment.java
@@ -15,6 +15,7 @@
*/
package com.android.contacts.list;
+import com.android.contacts.ContactPhotoManager;
import com.android.contacts.R;
import com.android.contacts.StrequentMetaDataLoader;
import com.android.contacts.list.ContactTileAdapter.DisplayType;
@@ -23,7 +24,6 @@
import android.app.Fragment;
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
-import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
@@ -49,29 +49,24 @@
private Listener mListener;
private ContactTileAdapter mAdapter;
private ListView mListView;
- private Context mContext;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mAdapter = new ContactTileAdapter(activity, mAdapterListener,
NUM_COLS, DisplayType.STREQUENT);
- mContext = activity;
+ mAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- View v = inflater.inflate(R.layout.strequent_fragment, container, false);
- mListView = (ListView) v.findViewById(R.id.strequent_list);
+ View v = inflater.inflate(R.layout.contact_tile_list, container, false);
+ mListView = (ListView) v.findViewById(R.id.contact_tile_list);
mListView.setItemsCanFocus(true);
return v;
}
- public void setListener(Listener listener) {
- mListener = listener;
- }
-
@Override
public void onStart(){
super.onStart();
@@ -86,7 +81,7 @@
@Override
public CursorLoader onCreateLoader(int id, Bundle args) {
- return new StrequentMetaDataLoader(mContext);
+ return new StrequentMetaDataLoader(getActivity());
}
@Override
@@ -101,6 +96,10 @@
}
};
+ public void setListener(Listener listener) {
+ mListener = listener;
+ }
+
private ContactTileAdapter.Listener mAdapterListener =
new ContactTileAdapter.Listener() {
@Override