Fixing issues with selection preservation including search
We have to do quite bit of work here because contact IDs
are unstable.
Change-Id: I461e1600cd686a2cf5e2dc6f931c7132853f7636
diff --git a/src/com/android/contacts/activities/ContactListActivity.java b/src/com/android/contacts/activities/ContactListActivity.java
index ed098a7..98fc88c 100644
--- a/src/com/android/contacts/activities/ContactListActivity.java
+++ b/src/com/android/contacts/activities/ContactListActivity.java
@@ -245,7 +245,6 @@
}
case NavigationBar.MODE_SEARCH: {
mListFragment = createContactSearchFragment();
- mListFragment.setQueryString(mNavigationBar.getQueryString());
break;
}
}
@@ -255,6 +254,12 @@
mListFragment.restoreSavedState(savedState);
}
+ if (mode == NavigationBar.MODE_SEARCH) {
+ mListFragment.setQueryString(mNavigationBar.getQueryString());
+ }
+
+ setupContactDetailFragment(mListFragment.getSelectedContactUri());
+
openFragmentTransaction()
.replace(R.id.two_pane_list, mListFragment)
.commit();
@@ -428,6 +433,7 @@
private final class ContactBrowserActionListener implements OnContactBrowserActionListener {
public void onViewContactAction(Uri contactLookupUri) {
if (mTwoPaneLayout) {
+ mListFragment.setSelectedContactUri(contactLookupUri);
setupContactDetailFragment(contactLookupUri);
} else {
startActivity(new Intent(Intent.ACTION_VIEW, contactLookupUri));
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index cfe0830..1e6f18e 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -17,7 +17,12 @@
import com.android.contacts.R;
+import android.content.CursorLoader;
+import android.content.Loader;
+import android.database.Cursor;
import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract.Contacts;
import android.widget.ListView;
/**
@@ -27,9 +32,68 @@
public abstract class ContactBrowseListFragment extends
ContactEntryListFragment<ContactListAdapter> {
+ private static final String KEY_SELECTED_URI = "selectedUri";
+
+ private static final int SELECTED_ID_LOADER = -3;
+
+ private Uri mSelectedContactUri;
+
private OnContactBrowserActionListener mListener;
@Override
+ public void restoreSavedState(Bundle savedState) {
+ super.restoreSavedState(savedState);
+
+ if (savedState == null) {
+ return;
+ }
+
+ mSelectedContactUri = savedState.getParcelable(KEY_SELECTED_URI);
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putParcelable(KEY_SELECTED_URI, mSelectedContactUri);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ if (mSelectedContactUri != null && isSelectionVisible()) {
+ startLoading(SELECTED_ID_LOADER, null);
+ }
+ }
+
+ @Override
+ protected Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ if (id == SELECTED_ID_LOADER) {
+ return new CursorLoader(getContext(),
+ mSelectedContactUri,
+ new String[] { Contacts._ID },
+ null,
+ null,
+ null);
+ }
+
+ return super.onCreateLoader(id, args);
+ }
+
+ @Override
+ protected void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ if (loader.getId() == SELECTED_ID_LOADER) {
+ long selectedId = ListView.INVALID_ROW_ID;
+ if (data.moveToFirst()) {
+ selectedId = data.getLong(0);
+ }
+ getAdapter().setSelectedContactId(selectedId);
+ return;
+ }
+
+ super.onLoadFinished(loader, data);
+ }
+
+ @Override
protected void prepareEmptyView() {
if (isSearchMode()) {
return;
@@ -48,6 +112,26 @@
}
}
+ public Uri getSelectedContactUri() {
+ return mSelectedContactUri;
+ }
+
+ public void setSelectedContactUri(Uri uri) {
+ if ((mSelectedContactUri == null && uri != null)
+ || (mSelectedContactUri != null && !mSelectedContactUri.equals(uri))) {
+ this.mSelectedContactUri = uri;
+ if (mSelectedContactUri != null) {
+ CursorLoader loader = (CursorLoader)getLoader(SELECTED_ID_LOADER);
+ if (loader == null) {
+ startLoading(SELECTED_ID_LOADER, null);
+ } else {
+ loader.setUri(mSelectedContactUri);
+ loader.forceLoad();
+ }
+ }
+ }
+ }
+
public void setOnContactListActionListener(OnContactBrowserActionListener listener) {
mListener = listener;
}
@@ -89,18 +173,4 @@
super.finish();
mListener.onFinishAction();
}
-
- @Override
- protected void completeRestoreInstanceState() {
- super.completeRestoreInstanceState();
- ListView listView = getListView();
- if (listView.getChoiceMode() == ListView.CHOICE_MODE_SINGLE) {
- Uri checkedUri = null;
- int position = listView.getCheckedItemPosition();
- if (position != -1) {
- checkedUri = getAdapter().getContactUri(position - listView.getHeaderViewsCount());
- }
- mListener.onViewContactAction(checkedUri);
- }
- }
}
diff --git a/src/com/android/contacts/list/ContactEntryListAdapter.java b/src/com/android/contacts/list/ContactEntryListAdapter.java
index dc75659..f71fd09 100644
--- a/src/com/android/contacts/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/list/ContactEntryListAdapter.java
@@ -61,6 +61,8 @@
private boolean mLoading = true;
private boolean mEmptyListEnabled = true;
+ private boolean mSelectionVisible;
+
public ContactEntryListAdapter(Context context) {
super(context, R.layout.list_section, R.id.header_text);
addPartitions();
@@ -195,6 +197,14 @@
mEmptyListEnabled = flag;
}
+ public boolean isSelectionVisible() {
+ return mSelectionVisible;
+ }
+
+ public void setSelectionVisible(boolean flag) {
+ this.mSelectionVisible = flag;
+ }
+
public void configureDirectoryLoader(DirectoryListLoader loader) {
loader.setDirectorySearchEnabled(mDirectorySearchEnabled);
}
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index 1cb8969..8c491a2 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -448,10 +448,6 @@
public void setSelectionVisible(boolean flag) {
this.mSelectionVisible = flag;
- if (mListView != null) {
- mListView.setChoiceMode(
- mSelectionVisible ? ListView.CHOICE_MODE_SINGLE : ListView.CHOICE_MODE_NONE);
- }
}
public void setSearchMode(boolean flag) {
@@ -591,9 +587,6 @@
// We manually save/restore the listview state
mListView.setSaveEnabled(false);
- mListView.setChoiceMode(
- mSelectionVisible ? ListView.CHOICE_MODE_SINGLE : ListView.CHOICE_MODE_NONE);
-
if (mContextMenuAdapter != null) {
mListView.setOnCreateContextMenuListener(mContextMenuAdapter);
}
@@ -631,6 +624,7 @@
mAdapter.setSortOrder(mSortOrder);
mAdapter.setNameHighlightingEnabled(isNameHighlighingEnabled());
mAdapter.setSectionHeaderDisplayEnabled(mSectionHeaderDisplayEnabled);
+ mAdapter.setSelectionVisible(mSelectionVisible);
}
protected boolean isNameHighlighingEnabled() {
diff --git a/src/com/android/contacts/list/ContactListAdapter.java b/src/com/android/contacts/list/ContactListAdapter.java
index 4c602c8..fd949ec 100644
--- a/src/com/android/contacts/list/ContactListAdapter.java
+++ b/src/com/android/contacts/list/ContactListAdapter.java
@@ -80,6 +80,8 @@
private int mDisplayNameColumnIndex;
private int mAlternativeDisplayNameColumnIndex;
+ private long mSelectedContactId;
+
public ContactListAdapter(Context context) {
super(context);
@@ -90,6 +92,17 @@
return mUnknownNameText;
}
+ public long getSelectedContactId() {
+ return mSelectedContactId;
+ }
+
+ public void setSelectedContactId(long selectedId) {
+ if (mSelectedContactId != selectedId) {
+ this.mSelectedContactId = selectedId;
+ notifyDataSetChanged();
+ }
+ }
+
protected static Uri buildSectionIndexerUri(Uri uri) {
return uri.buildUpon()
.appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
diff --git a/src/com/android/contacts/list/ContactListItemView.java b/src/com/android/contacts/list/ContactListItemView.java
index 2606425..102497a 100644
--- a/src/com/android/contacts/list/ContactListItemView.java
+++ b/src/com/android/contacts/list/ContactListItemView.java
@@ -29,33 +29,32 @@
import android.graphics.Canvas;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
-import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Nickname;
import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.provider.ContactsContract.Contacts;
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.Checkable;
import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
import android.widget.QuickContactBadge;
import android.widget.TextView;
-import android.widget.ImageView.ScaleType;
/**
* A custom view for an item in the contact list.
*/
-public class ContactListItemView extends ViewGroup implements Checkable {
+public class ContactListItemView extends ViewGroup {
private static final int QUICK_CONTACT_BADGE_STYLE =
com.android.internal.R.attr.quickContactBadgeStyleWindowMedium;
protected final Context mContext;
- private boolean mChecked;
+ private boolean mItemSelected;
private final int mPreferredHeight;
private final int mVerticalDividerMargin;
@@ -69,7 +68,7 @@
private final int mPresenceIconMargin;
private final int mHeaderTextWidth;
- private Drawable mCheckedBackgroundDrawable;
+ private Drawable mSelectedBackgroundDrawable;
private boolean mHorizontalDividerVisible = true;
private Drawable mHorizontalDividerDrawable;
@@ -267,9 +266,9 @@
topBound += mHeaderBackgroundHeight;
}
- if (mChecked) {
+ if (mItemSelected) {
ensureCheckedBackgroundDivider();
- mCheckedBackgroundDrawable.setBounds(0, topBound, width, height);
+ mSelectedBackgroundDrawable.setBounds(0, topBound, width, height);
}
// Positions of views on the left are fixed and so are those on the right side.
@@ -405,10 +404,10 @@
* Loads the drawable for the item background used when the item is checked.
*/
private void ensureCheckedBackgroundDivider() {
- if (mCheckedBackgroundDrawable == null) {
- mCheckedBackgroundDrawable = mContext.getResources().getDrawable(
+ if (mSelectedBackgroundDrawable == null) {
+ mSelectedBackgroundDrawable = mContext.getResources().getDrawable(
R.drawable.list_item_checked_bg);
- mCheckedBackgroundDrawable.setBounds(0, 0, getWidth(), getHeight());
+ mSelectedBackgroundDrawable.setBounds(0, 0, getWidth(), getHeight());
}
}
@@ -465,8 +464,8 @@
@Override
public void dispatchDraw(Canvas canvas) {
- if (mChecked) {
- mCheckedBackgroundDrawable.draw(canvas);
+ if (mItemSelected) {
+ mSelectedBackgroundDrawable.draw(canvas);
}
if (mHeaderVisible) {
mHeaderBackgroundDrawable.draw(canvas);
@@ -844,21 +843,14 @@
setData(dataBuffer.data, dataBuffer.sizeCopied);
}
- @Override
- public boolean isChecked() {
- return mChecked;
+ public boolean isItemSelected() {
+ return mItemSelected;
}
- @Override
- public void setChecked(boolean checked) {
- if (mChecked != checked) {
- mChecked = checked;
+ public void setItemSelected(boolean selected) {
+ if (mItemSelected != selected) {
+ mItemSelected = selected;
requestLayout();
}
}
-
- @Override
- public void toggle() {
- setChecked(!mChecked);
- }
}
diff --git a/src/com/android/contacts/list/DefaultContactListAdapter.java b/src/com/android/contacts/list/DefaultContactListAdapter.java
index 14c09e6..c1bb1e8 100644
--- a/src/com/android/contacts/list/DefaultContactListAdapter.java
+++ b/src/com/android/contacts/list/DefaultContactListAdapter.java
@@ -98,6 +98,10 @@
protected void bindView(View itemView, int partition, Cursor cursor, int position) {
final ContactListItemView view = (ContactListItemView)itemView;
+ if (isSelectionVisible()) {
+ view.setItemSelected(getSelectedContactId() == cursor.getLong(CONTACT_ID_COLUMN_INDEX));
+ }
+
bindSectionHeaderAndDivider(view, position);
if (isQuickContactEnabled()) {
diff --git a/src/com/android/contacts/list/StrequentContactListAdapter.java b/src/com/android/contacts/list/StrequentContactListAdapter.java
index b5aec28..c198c38 100644
--- a/src/com/android/contacts/list/StrequentContactListAdapter.java
+++ b/src/com/android/contacts/list/StrequentContactListAdapter.java
@@ -198,6 +198,10 @@
protected void bindView(View itemView, int partition, Cursor cursor, int position) {
final ContactListItemView view = (ContactListItemView)itemView;
+ if (isSelectionVisible()) {
+ view.setItemSelected(getSelectedContactId() == cursor.getLong(CONTACT_ID_COLUMN_INDEX));
+ }
+
bindName(view, cursor);
bindQuickContact(view, cursor);
bindPresence(view, cursor);