Refactoring ContactEntryListFragment/Adapter
Refactoring for better separation of their respective roles.
Change-Id: Ie11e92a98f31f6a4c0d097109ef1f3977adb5f74
diff --git a/src/com/android/contacts/list/ContactEntryListAdapter.java b/src/com/android/contacts/list/ContactEntryListAdapter.java
index f7f4fdb..ff402a2 100644
--- a/src/com/android/contacts/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/list/ContactEntryListAdapter.java
@@ -23,17 +23,20 @@
import android.content.Context;
import android.content.CursorLoader;
+import android.content.pm.PackageManager;
import android.database.Cursor;
+import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.ContactCounts;
+import android.provider.ContactsContract.Directory;
import android.text.TextUtils;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-import java.util.HashMap;
-import java.util.Iterator;
+import java.util.HashSet;
/**
* Common base class for various contact-related lists, e.g. contact list, phone number list
@@ -43,6 +46,23 @@
private static final String TAG = "ContactEntryListAdapter";
+ private static final class DirectoryQuery {
+ public static final Uri URI = Directory.CONTENT_URI;
+ public static final String ORDER_BY = Directory._ID;
+
+ public static final String[] PROJECTION = {
+ Directory._ID,
+ Directory.PACKAGE_NAME,
+ Directory.TYPE_RESOURCE_ID,
+ Directory.DISPLAY_NAME,
+ };
+
+ public static final int ID = 0;
+ public static final int PACKAGE_NAME = 1;
+ public static final int TYPE_RESOURCE_ID = 2;
+ public static final int DISPLAY_NAME = 3;
+ }
+
/**
* The animation is used here to allocate animated name text views.
*/
@@ -61,28 +81,34 @@
private boolean mLoading = true;
private boolean mEmptyListEnabled = true;
- private HashMap<Integer, DirectoryPartition> mPartitions;
-
public ContactEntryListAdapter(Context context) {
super(context, R.layout.list_section, R.id.header_text);
addPartitions();
}
- /**
- * Adds all partitions this adapter will handle. The default implementation
- * creates one partition with no header.
- */
protected void addPartitions() {
- addPartition(false, false);
+ addPartition(createDefaultDirectoryPartition());
}
- public void addDirectoryPartition(DirectoryPartition partition) {
- if (mPartitions == null) {
- mPartitions = new HashMap<Integer, DirectoryPartition>();
+ protected DirectoryPartition createDefaultDirectoryPartition() {
+ DirectoryPartition partition = new DirectoryPartition(true, true);
+ partition.setDirectoryId(Directory.DEFAULT);
+ partition.setDirectoryType(getContext().getString(R.string.contactsList));
+ partition.setPriorityDirectory(true);
+ return partition;
+ }
+
+ private int getPartitionByDirectoryId(long id) {
+ int count = getPartitionCount();
+ for (int i = 0; i < count; i++) {
+ Partition partition = getPartition(i);
+ if (partition instanceof DirectoryPartition) {
+ if (((DirectoryPartition)partition).getDirectoryId() == id) {
+ return i;
+ }
+ }
}
- int partitionIndex = getPartitionCount();
- mPartitions.put(partitionIndex, partition);
- addPartition(partition.getShowIfEmpty(), partition.getDirectoryType() != null);
+ return -1;
}
public abstract String getContactDisplayName(int position);
@@ -93,10 +119,13 @@
*/
public void onDataReload() {
boolean notify = false;
- if (mPartitions != null) {
- for (DirectoryPartition partition : mPartitions.values()) {
- if (!partition.isLoading()) {
- partition.setLoading(true);
+ int count = getPartitionCount();
+ for (int i = 0; i < count; i++) {
+ Partition partition = getPartition(i);
+ if (partition instanceof DirectoryPartition) {
+ DirectoryPartition directoryPartition = (DirectoryPartition)partition;
+ if (!directoryPartition.isLoading()) {
+ directoryPartition.setLoading(true);
notify = true;
}
}
@@ -111,12 +140,21 @@
}
public void setSearchMode(boolean flag) {
- if (mSearchMode != flag) {
- mSearchMode = flag;
+ mSearchMode = flag;
- // Search mode change may mean a new data type in the list.
- // Let's drop current data to avoid confusion
- resetPartitions();
+ int defaultPartitionIndex = -1;
+ int count = getPartitionCount();
+ for (int i = 0; i < count; i++) {
+ Partition partition = getPartition(i);
+ if (partition instanceof DirectoryPartition &&
+ ((DirectoryPartition)partition).getDirectoryId() == Directory.DEFAULT) {
+ defaultPartitionIndex = i;
+ break;
+ }
+ }
+ if (defaultPartitionIndex != -1) {
+ setShowIfEmpty(defaultPartitionIndex, flag);
+ setHasHeader(defaultPartitionIndex, flag);
}
}
@@ -192,11 +230,74 @@
mEmptyListEnabled = flag;
}
+ public void configureDirectoryLoader(CursorLoader loader) {
+ loader.setUri(DirectoryQuery.URI);
+ loader.setProjection(DirectoryQuery.PROJECTION);
+ loader.setSortOrder(DirectoryQuery.ORDER_BY);
+ }
+
+ /**
+ * Updates partitions according to the directory meta-data contained in the supplied
+ * cursor. Takes ownership of the cursor and will close it.
+ */
+ public void changeDirectories(Cursor cursor) {
+ HashSet<Long> directoryIds = new HashSet<Long>();
+
+ // TODO preserve the order of partition to match those of the cursor
+ // Phase I: add new directories
+ try {
+ while (cursor.moveToNext()) {
+ long id = cursor.getLong(DirectoryQuery.ID);
+ directoryIds.add(id);
+ if (getPartitionByDirectoryId(id) == -1) {
+ DirectoryPartition partition = createDirectoryPartition(cursor);
+ addPartition(partition);
+ }
+ }
+ } finally {
+ cursor.close();
+ }
+
+ // Phase II: remove deleted directories
+ int count = getPartitionCount();
+ for (int i = count; --i >= 0; ) {
+ Partition partition = getPartition(i);
+ if (partition instanceof DirectoryPartition) {
+ long id = ((DirectoryPartition)partition).getDirectoryId();
+ if (!directoryIds.contains(id)) {
+ removePartition(i);
+ }
+ }
+ }
+
+ invalidate();
+ notifyDataSetChanged();
+ }
+
+ private DirectoryPartition createDirectoryPartition(Cursor cursor) {
+ PackageManager pm = getContext().getPackageManager();
+ DirectoryPartition partition = new DirectoryPartition(false, true);
+ partition.setDirectoryId(cursor.getLong(DirectoryQuery.ID));
+ String packageName = cursor.getString(DirectoryQuery.PACKAGE_NAME);
+ int typeResourceId = cursor.getInt(DirectoryQuery.TYPE_RESOURCE_ID);
+ if (!TextUtils.isEmpty(packageName) && typeResourceId != 0) {
+ // TODO: should this be done on a background thread?
+ try {
+ partition.setDirectoryType(pm.getResourcesForApplication(packageName)
+ .getString(typeResourceId));
+ } catch (Exception e) {
+ Log.e(TAG, "Cannot obtain directory type from package: " + packageName);
+ }
+ }
+ partition.setDisplayName(cursor.getString(DirectoryQuery.DISPLAY_NAME));
+ return partition;
+ }
+
@Override
public void changeCursor(int partitionIndex, Cursor cursor) {
- if (mPartitions != null) {
- DirectoryPartition partition = mPartitions.get(partitionIndex);
- partition.setLoading(false);
+ Partition partition = getPartition(partitionIndex);
+ if (partition instanceof DirectoryPartition) {
+ ((DirectoryPartition)partition).setLoading(false);
}
super.changeCursor(partitionIndex, cursor);
@@ -258,20 +359,24 @@
@Override
protected void bindHeaderView(View view, int partitionIndex, Cursor cursor) {
- DirectoryPartition partition = mPartitions.get(partitionIndex);
+ Partition partition = getPartition(partitionIndex);
+ if (!(partition instanceof DirectoryPartition)) {
+ return;
+ }
+ DirectoryPartition directoryPartition = (DirectoryPartition)partition;
TextView directoryTypeTextView = (TextView)view.findViewById(R.id.directory_type);
- directoryTypeTextView.setText(partition.getDirectoryType());
+ directoryTypeTextView.setText(directoryPartition.getDirectoryType());
TextView displayNameTextView = (TextView)view.findViewById(R.id.display_name);
- if (!TextUtils.isEmpty(partition.getDisplayName())) {
- displayNameTextView.setText(partition.getDisplayName());
+ if (!TextUtils.isEmpty(directoryPartition.getDisplayName())) {
+ displayNameTextView.setText(directoryPartition.getDisplayName());
displayNameTextView.setVisibility(View.VISIBLE);
} else {
displayNameTextView.setVisibility(View.GONE);
}
TextView countText = (TextView)view.findViewById(R.id.count);
- if (partition.isLoading()) {
+ if (directoryPartition.isLoading()) {
countText.setText(R.string.search_results_searching);
} else {
int count = cursor == null ? 0 : cursor.getCount();
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index 8c2abb3..9bfdbb3 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -23,7 +23,7 @@
import com.android.contacts.R;
import com.android.contacts.ui.ContactsPreferences;
import com.android.contacts.widget.ContextMenuAdapter;
-import com.google.android.collect.Lists;
+import com.android.contacts.widget.CompositeCursorAdapter.Partition;
import android.accounts.Account;
import android.accounts.AccountManager;
@@ -36,10 +36,8 @@
import android.content.IContentService;
import android.content.Intent;
import android.content.Loader;
-import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.database.Cursor;
-import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
@@ -68,8 +66,6 @@
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView.OnItemClickListener;
-import java.util.ArrayList;
-
/**
* Common base class for various contact-related list fragments.
*/
@@ -87,8 +83,6 @@
private static final int DIRECTORY_LOADER_ID = -1;
- private ArrayList<DirectoryPartition> mDirectoryPartitions = Lists.newArrayList();
-
private boolean mSectionHeaderDisplayEnabled;
private boolean mPhotoLoaderEnabled;
private boolean mSearchMode;
@@ -118,31 +112,17 @@
private int mProviderStatus = ProviderStatus.STATUS_NORMAL;
+ private boolean mForceLoad;
+ private boolean mLoadDirectoryList;
+
/**
* Indicates whether we are doing the initial complete load of data or
* a refresh caused by a change notification.
*/
- private boolean mInitialLoadComplete;
+ private boolean mLoadPriorityDirectoriesOnly;
private ContactsRequest mRequest;
- private static final class DirectoryQuery {
- public static final Uri URI = Directory.CONTENT_URI;
- public static final String ORDER_BY = Directory._ID;
-
- public static final String[] PROJECTION = {
- Directory._ID,
- Directory.PACKAGE_NAME,
- Directory.TYPE_RESOURCE_ID,
- Directory.DISPLAY_NAME,
- };
-
- public static final int ID = 0;
- public static final int PACKAGE_NAME = 1;
- public static final int TYPE_RESOURCE_ID = 2;
- public static final int DISPLAY_NAME = 3;
- }
-
protected abstract View inflateView(LayoutInflater inflater, ViewGroup container);
protected abstract T createListAdapter();
@@ -200,42 +180,58 @@
loadPreferences(mContactsPrefs);
- configureAdapter();
-
- if (isSearchMode()) {
- if (mInitialLoadComplete) {
- for (DirectoryPartition partition : mDirectoryPartitions) {
- if (partition.getPartitionIndex() != 0) {
- startLoading(partition, true);
- }
- }
- } else {
- startLoading(0, null);
- }
- } else {
- startLoading(0, null);
+ if (mListView instanceof ContactEntryListView) {
+ ContactEntryListView listView = (ContactEntryListView)mListView;
+ listView.setHighlightNamesWhenScrolling(isNameHighlighingEnabled());
}
- ContactEntryListView listView = (ContactEntryListView)mListView;
- listView.setHighlightNamesWhenScrolling(isNameHighlighingEnabled());
-
+ mForceLoad = false;
+ mLoadDirectoryList = true;
+ mLoadPriorityDirectoriesOnly = true;
+ startLoading();
super.onStart();
}
+ private void startLoading() {
+ configureAdapter();
+ int partitionCount = mAdapter.getPartitionCount();
+ for (int i = 0; i < partitionCount; i++) {
+ Partition partition = mAdapter.getPartition(i);
+ if (partition instanceof DirectoryPartition) {
+ DirectoryPartition directoryPartition = (DirectoryPartition)partition;
+ if (mLoadPriorityDirectoriesOnly == directoryPartition.isPriorityDirectory()) {
+ startLoadingDirectoryPartition(i);
+ }
+ } else {
+ startLoading(i, null);
+ }
+ }
+ }
+
@Override
protected Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ CursorLoader loader = new CursorLoader(getActivity(), null, null, null, null, null);
if (id == DIRECTORY_LOADER_ID) {
- return new CursorLoader(getActivity(), DirectoryQuery.URI, DirectoryQuery.PROJECTION,
- null, null, DirectoryQuery.ORDER_BY);
+ mAdapter.configureDirectoryLoader(loader);
} else {
- CursorLoader loader = new CursorLoader(getActivity(), null, null, null, null, null);
- if (mAdapter != null) {
- long directoryId = args != null && args.containsKey(DIRECTORY_ID_ARG_KEY)
- ? args.getLong(DIRECTORY_ID_ARG_KEY)
- : Directory.DEFAULT;
- mAdapter.configureLoader(loader, directoryId);
- }
- return loader;
+ long directoryId = args != null && args.containsKey(DIRECTORY_ID_ARG_KEY)
+ ? args.getLong(DIRECTORY_ID_ARG_KEY)
+ : Directory.DEFAULT;
+ mAdapter.configureLoader(loader, directoryId);
+ }
+ return loader;
+ }
+
+ private void startLoadingDirectoryPartition(int partitionIndex) {
+ DirectoryPartition partition = (DirectoryPartition)mAdapter.getPartition(partitionIndex);
+ CursorLoader loader = (CursorLoader)getLoader(partitionIndex);
+ if (loader == null) {
+ Bundle args = new Bundle();
+ args.putLong(DIRECTORY_ID_ARG_KEY, partition.getDirectoryId());
+ startLoading(partitionIndex, args);
+ } else if (mForceLoad) {
+ mAdapter.configureLoader(loader, partition.getDirectoryId());
+ loader.forceLoad();
}
}
@@ -248,15 +244,27 @@
return;
}
- int partitionIndex = loader.getId();
- if (!mInitialLoadComplete) {
- onInitialLoadFinished(partitionIndex, data);
+ int loaderId = loader.getId();
+ if (loaderId == DIRECTORY_LOADER_ID) {
+ mAdapter.changeDirectories(data);
} else {
- onRequeryFinished(partitionIndex, data);
+ final int partitionIndex = loaderId; // by convention
+ mAdapter.changeCursor(partitionIndex, data);
+ showCount(partitionIndex, data);
+ if (partitionIndex == mAdapter.getIndexedPartition()) {
+ mAizy.setIndexer(mAdapter.getIndexer());
+ }
+ completeRestoreInstanceState();
}
- if (partitionIndex == mAdapter.getIndexedPartition()) {
- mAizy.setIndexer(mAdapter.getIndexer());
+ if (isSearchMode()) {
+ if (mLoadDirectoryList) {
+ mLoadDirectoryList = false;
+ startLoading(DIRECTORY_LOADER_ID, null);
+ } else if (mLoadPriorityDirectoriesOnly) {
+ mLoadPriorityDirectoriesOnly = false;
+ startLoading();
+ }
}
// TODO fix the empty view
@@ -265,149 +273,28 @@
// }
}
- private void onInitialLoadFinished(int partitionIndex, Cursor data) {
- if (partitionIndex == 0) {
- mDirectoryPartitions.clear();
- mAdapter.resetPartitions();
- DirectoryPartition partition = new DirectoryPartition();
- partition.setDirectoryId(Directory.DEFAULT);
- partition.setShowIfEmpty(isSearchMode());
- partition.setDirectoryType(getActivity().getString(R.string.contactsList));
- mDirectoryPartitions.add(partition);
- if (isSearchMode()) {
- mAdapter.addDirectoryPartition(partition);
- } else {
- mAdapter.addPartition(false, false);
- }
- mAdapter.changeCursor(partitionIndex, data);
- showCount(partitionIndex, data);
- if (data != null) {
- completeRestoreInstanceState();
- }
- if (isSearchMode()) {
- startLoading(DIRECTORY_LOADER_ID, null);
- } else {
- mInitialLoadComplete = true;
- }
- } else if (partitionIndex == DIRECTORY_LOADER_ID) {
- try {
- for (int index = 0; data.moveToNext(); index++) {
- DirectoryPartition partition = createDirectoryPartition(index, data);
- if (index != 0) {
- mDirectoryPartitions.add(partition);
- mAdapter.addDirectoryPartition(partition);
- startLoading(partition, false);
- }
- }
- } finally {
- data.close();
- }
-
- mInitialLoadComplete = true;
- }
- }
-
- private void onRequeryFinished(int partitionIndex, Cursor data) {
- if (partitionIndex == 0) {
- mAdapter.changeCursor(partitionIndex, data);
- showCount(partitionIndex, data);
- int size = mDirectoryPartitions.size();
- for (int i = 1; i < size; i++) {
- startLoading(mDirectoryPartitions.get(i), true);
- }
- } else if (partitionIndex == DIRECTORY_LOADER_ID) {
- // The list of available directories has changed: reload everything
- try {
- mDirectoryPartitions.clear();
- mAdapter.resetPartitions();
- for (int index = 0; data.moveToNext(); index++) {
- DirectoryPartition partition = createDirectoryPartition(index, data);
- mDirectoryPartitions.add(partition);
- mAdapter.addDirectoryPartition(partition);
- }
- } finally {
- data.close();
- }
- reloadData();
- } else {
- mAdapter.changeCursor(partitionIndex, data);
- showCount(partitionIndex, data);
- }
- }
-
- private DirectoryPartition createDirectoryPartition(int partitionIndex, Cursor cursor) {
- PackageManager pm = getActivity().getPackageManager();
- DirectoryPartition partition = new DirectoryPartition();
- partition.setPartitionIndex(partitionIndex);
- partition.setDirectoryId(cursor.getLong(DirectoryQuery.ID));
- String packageName = cursor.getString(DirectoryQuery.PACKAGE_NAME);
- int typeResourceId = cursor.getInt(DirectoryQuery.TYPE_RESOURCE_ID);
- if (!TextUtils.isEmpty(packageName) && typeResourceId != 0) {
- // TODO: should this be done on a background thread?
- try {
- partition.setDirectoryType(pm.getResourcesForApplication(packageName)
- .getString(typeResourceId));
- } catch (Exception e) {
- Log.e(TAG, "Cannot obtain directory type from package: " + packageName);
- }
- }
- partition.setDisplayName(cursor.getString(DirectoryQuery.DISPLAY_NAME));
- partition.setShowIfEmpty(partition.getDirectoryId() == Directory.DEFAULT);
- return partition;
- }
-
- private void startLoading(DirectoryPartition partition, boolean forceLoad) {
- CursorLoader loader = (CursorLoader)getLoader(partition.getPartitionIndex());
- if (loader == null) {
- Bundle args = new Bundle();
- args.putLong(DIRECTORY_ID_ARG_KEY, partition.getDirectoryId());
- startLoading(partition.getPartitionIndex(), args);
- } else {
- mAdapter.configureLoader(loader, partition.getDirectoryId());
- if (forceLoad) {
- loader.forceLoad();
- }
- }
- }
-
protected void reloadData() {
- if (mInitialLoadComplete) {
- mAdapter.onDataReload();
- if (mDirectoryPartitions.size() > 0) {
- // We need to cancel _all_ current queries and then launch
- // a new query for the 0th partition.
-
- CursorLoader directoryLoader = (CursorLoader)getLoader(DIRECTORY_LOADER_ID);
- if (directoryLoader != null) {
- directoryLoader.cancelLoad();
- }
- int size = mDirectoryPartitions.size();
- for (int i = 0; i < size; i++) {
- CursorLoader loader = (CursorLoader)getLoader(i);
- if (loader != null) {
- loader.cancelLoad();
- }
- }
-
- startLoading(mDirectoryPartitions.get(0), true);
- }
- } else {
- startLoading(0, null);
- }
+ cancelLoading();
+ mAdapter.onDataReload();
+ mLoadPriorityDirectoriesOnly = true;
+ mForceLoad = true;
+ startLoading();
}
- private void stopLoading() {
- stopLoading(DIRECTORY_LOADER_ID);
- for (DirectoryPartition partition : mDirectoryPartitions) {
- stopLoading(partition.getPartitionIndex());
+ private void cancelLoading() {
+ int size = mAdapter.getPartitionCount();
+ for (int i = 0; i < size; i++) {
+ CursorLoader loader = (CursorLoader)getLoader(i);
+ if (loader != null) {
+ loader.cancelLoad();
+ }
}
}
@Override
public void onStop() {
super.onStop();
- mAdapter.resetPartitions();
- mInitialLoadComplete = false;
+ mAdapter.clearPartitions();
}
/**
@@ -476,14 +363,15 @@
public void setSearchMode(boolean flag) {
if (mSearchMode != flag) {
mSearchMode = flag;
- // TODO not always
setSectionHeaderDisplayEnabled(!mSearchMode);
+
if (mAdapter != null) {
- stopLoading();
+ mAdapter.clearPartitions();
mAdapter.setSearchMode(flag);
mAdapter.setPinnedPartitionHeadersEnabled(flag);
- mInitialLoadComplete = false;
+ reloadData();
}
+
if (mListView != null) {
mListView.setFastScrollEnabled(!flag);
}
@@ -665,6 +553,7 @@
if (mAdapter == null) {
return;
}
+
mAdapter.setQueryString(mQueryString);
mAdapter.setPinnedPartitionHeadersEnabled(mSearchMode);
mAdapter.setContactNameDisplayOrder(mDisplayOrder);
diff --git a/src/com/android/contacts/list/DirectoryPartition.java b/src/com/android/contacts/list/DirectoryPartition.java
index b76b97a..d7cb9bc 100644
--- a/src/com/android/contacts/list/DirectoryPartition.java
+++ b/src/com/android/contacts/list/DirectoryPartition.java
@@ -15,19 +15,23 @@
*/
package com.android.contacts.list;
-import android.database.Cursor;
+import com.android.contacts.widget.CompositeCursorAdapter;
+
import android.provider.ContactsContract.Directory;
/**
* Model object for a {@link Directory} row.
*/
-public final class DirectoryPartition {
+public final class DirectoryPartition extends CompositeCursorAdapter.Partition {
private long mDirectoryId;
- private int mPartitionIndex;
private String mDirectoryType;
private String mDisplayName;
- private boolean mShowIfEmpty;
private boolean mLoading;
+ private boolean mPriorityDirectory;
+
+ public DirectoryPartition(boolean showIfEmpty, boolean hasHeader) {
+ super(showIfEmpty, hasHeader);
+ }
/**
* Directory ID, see {@link Directory}.
@@ -41,17 +45,6 @@
}
/**
- * Corresponding loader ID.
- */
- public int getPartitionIndex() {
- return mPartitionIndex;
- }
-
- public void setPartitionIndex(int partitionIndex) {
- this.mPartitionIndex = partitionIndex;
- }
-
- /**
* Directory type resolved from {@link Directory#PACKAGE_NAME} and
* {@link Directory#TYPE_RESOURCE_ID};
*/
@@ -74,17 +67,6 @@
this.mDisplayName = displayName;
}
- /**
- * True if the directory should be shown even if no contacts are found.
- */
- public boolean getShowIfEmpty() {
- return mShowIfEmpty;
- }
-
- public void setShowIfEmpty(boolean showIfEmpty) {
- this.mShowIfEmpty = showIfEmpty;
- }
-
public boolean isLoading() {
return mLoading;
}
@@ -92,4 +74,15 @@
public void setLoading(boolean loading) {
mLoading = loading;
}
+
+ /**
+ * Returns true if this directory should be loaded before non-priority directories.
+ */
+ public boolean isPriorityDirectory() {
+ return mPriorityDirectory;
+ }
+
+ public void setPriorityDirectory(boolean priorityDirectory) {
+ mPriorityDirectory = priorityDirectory;
+ }
}
diff --git a/src/com/android/contacts/widget/CompositeCursorAdapter.java b/src/com/android/contacts/widget/CompositeCursorAdapter.java
index c6d2ea3..147ed42 100644
--- a/src/com/android/contacts/widget/CompositeCursorAdapter.java
+++ b/src/com/android/contacts/widget/CompositeCursorAdapter.java
@@ -29,18 +29,29 @@
private static final int INITIAL_CAPACITY = 2;
- private static class Partition {
- final boolean showIfEmpty;
- final boolean hasHeader;
+ public static class Partition {
+ boolean showIfEmpty;
+ boolean hasHeader;
- int count;
Cursor cursor;
int idColumnIndex;
+ int count;
public Partition(boolean showIfEmpty, boolean hasHeader) {
this.showIfEmpty = showIfEmpty;
this.hasHeader = hasHeader;
}
+
+ /**
+ * True if the directory should be shown even if no contacts are found.
+ */
+ public boolean getShowIfEmpty() {
+ return showIfEmpty;
+ }
+
+ public boolean getHasHeader() {
+ return hasHeader;
+ }
}
private final Context mContext;
@@ -68,29 +79,65 @@
* list.
*/
public void addPartition(boolean showIfEmpty, boolean hasHeader) {
+ addPartition(new Partition(showIfEmpty, hasHeader));
+ }
+
+ public void addPartition(Partition partition) {
if (mSize >= mPartitions.length) {
int newCapacity = mSize + 2;
Partition[] newAdapters = new Partition[newCapacity];
System.arraycopy(mPartitions, 0, newAdapters, 0, mSize);
mPartitions = newAdapters;
}
- mPartitions[mSize++] = new Partition(showIfEmpty, hasHeader);
+ mPartitions[mSize++] = partition;
invalidate();
notifyDataSetChanged();
}
- public void resetPartitions() {
+ public void removePartition(int partitionIndex) {
+ Cursor cursor = mPartitions[partitionIndex].cursor;
+ if (cursor != null && !cursor.isClosed()) {
+ cursor.close();
+ }
+
+ System.arraycopy(mPartitions, partitionIndex + 1, mPartitions, partitionIndex, mSize - 1);
+ mSize--;
+ invalidate();
+ notifyDataSetChanged();
+ }
+
+ /**
+ * Removes cursors for all partitions, closing them as necessary.
+ */
+ public void clearPartitions() {
for (int i = 0; i < mSize; i++) {
Cursor cursor = mPartitions[i].cursor;
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
+ mPartitions[i].cursor = null;
}
- mSize = 0;
invalidate();
notifyDataSetChanged();
}
+ public void setHasHeader(int partitionIndex, boolean flag) {
+ mPartitions[partitionIndex].hasHeader = flag;
+ invalidate();
+ }
+
+ public void setShowIfEmpty(int partitionIndex, boolean flag) {
+ mPartitions[partitionIndex].showIfEmpty = flag;
+ invalidate();
+ }
+
+ public Partition getPartition(int partitionIndex) {
+ if (partitionIndex >= mSize) {
+ throw new ArrayIndexOutOfBoundsException(partitionIndex);
+ }
+ return mPartitions[partitionIndex];
+ }
+
protected void invalidate() {
mCacheValid = false;
}