Join activity is converted to loaders/fragments
Change-Id: I3d02fac52daffa5e0921a05fcad6932bc94e7274
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 10a0645..05797f3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -386,7 +386,7 @@
<!-- Edit or insert details for a contact -->
<activity
- android:name=".activities.ContactEditActivity"
+ android:name=".ui.EditContactActivity"
android:windowSoftInputMode="stateHidden|adjustResize">
<intent-filter android:label="@string/editContactDescription">
diff --git a/res/layout-finger/contacts_list_content_join.xml b/res/layout-finger/contacts_list_content_join.xml
index b50713b..b59c240 100644
--- a/res/layout-finger/contacts_list_content_join.xml
+++ b/res/layout-finger/contacts_list_content_join.xml
@@ -61,10 +61,12 @@
</LinearLayout>
</LinearLayout>
- <ListView android:id="@android:id/list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fastScrollEnabled="true"
+ <view
+ class="com.android.contacts.ContactEntryListView"
+ android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fastScrollEnabled="true"
/>
</LinearLayout>
diff --git a/src/com/android/contacts/JoinContactActivity.java b/src/com/android/contacts/JoinContactActivity.java
index 9024e0b..501739d 100644
--- a/src/com/android/contacts/JoinContactActivity.java
+++ b/src/com/android/contacts/JoinContactActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2009 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.
@@ -17,28 +17,21 @@
package com.android.contacts;
-import com.android.contacts.list.JoinContactListAdapter;
import com.android.contacts.list.JoinContactListFragment;
-import com.android.internal.telephony.gsm.stk.ResultCode;
+import com.android.contacts.list.OnContactPickerActionListener;
-import android.content.ContentUris;
+import android.app.Activity;
+import android.app.FragmentTransaction;
import android.content.Intent;
-import android.database.Cursor;
-import android.database.MatrixCursor;
import android.net.Uri;
-import android.net.Uri.Builder;
+import android.os.Bundle;
import android.provider.ContactsContract;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Contacts.AggregationSuggestions;
-import android.text.TextUtils;
import android.util.Log;
-import android.widget.ListView;
-import android.widget.TextView;
/**
* An activity that shows a list of contacts that can be joined with the target contact.
*/
-public class JoinContactActivity extends ContactsListActivity {
+public class JoinContactActivity extends Activity {
private static final String TAG = "JoinContactActivity";
@@ -57,153 +50,43 @@
*/
public static final String EXTRA_TARGET_CONTACT_ID = "com.android.contacts.action.CONTACT_ID";
- /** Maximum number of suggestions shown for joining aggregates */
- private static final int MAX_SUGGESTIONS = 4;
-
private long mTargetContactId;
- /**
- * The ID of the special item described above.
- */
- private static final long JOIN_MODE_SHOW_ALL_CONTACTS_ID = -2;
-
- private boolean mLoadingJoinSuggestions;
-
- private JoinContactListAdapter mAdapter;
-
@Override
- protected boolean resolveIntent(Intent intent) {
- mMode = MODE_PICK_CONTACT;
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Intent intent = getIntent();
mTargetContactId = intent.getLongExtra(EXTRA_TARGET_CONTACT_ID, -1);
if (mTargetContactId == -1) {
Log.e(TAG, "Intent " + intent.getAction() + " is missing required extra: "
+ EXTRA_TARGET_CONTACT_ID);
setResult(RESULT_CANCELED);
finish();
- return false;
+ return;
}
- mListFragment = new JoinContactListFragment();
-
- return true;
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-
- // TODO move this to onAttach of the corresponding fragment
- TextView blurbView = (TextView)findViewById(R.id.join_contact_blurb);
-
- String blurb = getString(R.string.blurbJoinContactDataWith,
- getContactDisplayName(mTargetContactId));
- blurbView.setText(blurb);
-
- ListView listView = (ListView)findViewById(android.R.id.list);
- mAdapter = (JoinContactListAdapter)listView.getAdapter();
- mAdapter.setJoinModeShowAllContacts(true);
- }
-
- @Override
- public void onListItemClick(int position, long id) {
- if (id == JOIN_MODE_SHOW_ALL_CONTACTS_ID) {
- mAdapter.setJoinModeShowAllContacts(false);
- startQuery();
- } else {
- final Uri uri = getSelectedUri(position);
- setResult(RESULT_OK, new Intent(null, uri));
- finish();
- }
- }
-
- @Override
- protected Uri getUriToQuery() {
- return getJoinSuggestionsUri(null);
- }
-
- /*
- * TODO: move to a background thread.
- */
- private String getContactDisplayName(long contactId) {
- String contactName = null;
- Cursor c = getContentResolver().query(
- ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
- new String[] {Contacts.DISPLAY_NAME}, null, null, null);
- try {
- if (c != null && c.moveToFirst()) {
- contactName = c.getString(0);
- }
- } finally {
- if (c != null) {
- c.close();
- }
- }
-
- if (contactName == null) {
- contactName = "";
- }
-
- return contactName;
- }
-
- private Uri getJoinSuggestionsUri(String filter) {
- Builder builder = Contacts.CONTENT_URI.buildUpon();
- builder.appendEncodedPath(String.valueOf(mTargetContactId));
- builder.appendEncodedPath(AggregationSuggestions.CONTENT_DIRECTORY);
- if (!TextUtils.isEmpty(filter)) {
- builder.appendEncodedPath(Uri.encode(filter));
- }
- builder.appendQueryParameter("limit", String.valueOf(MAX_SUGGESTIONS));
- return builder.build();
- }
-
- @Override
- public
- Cursor doFilter(String filter) {
- throw new UnsupportedOperationException();
- }
-
- private Cursor getShowAllContactsLabelCursor(String[] projection) {
- MatrixCursor matrixCursor = new MatrixCursor(projection);
- Object[] row = new Object[projection.length];
- // The only columns we care about is the id
- row[SUMMARY_ID_COLUMN_INDEX] = JOIN_MODE_SHOW_ALL_CONTACTS_ID;
- matrixCursor.addRow(row);
- return matrixCursor;
- }
-
- @Override
- protected void startQuery(Uri uri, String[] projection) {
- mLoadingJoinSuggestions = true;
- startQuery(uri, projection, null, null, null);
- }
-
- @Override
- protected void onQueryComplete(Cursor cursor) {
- // Whenever we get a suggestions cursor, we need to immediately kick off
- // another query for the complete list of contacts
- if (cursor != null && mLoadingJoinSuggestions) {
- mLoadingJoinSuggestions = false;
- if (cursor.getCount() > 0) {
- mAdapter.setSuggestionsCursor(cursor);
- } else {
- cursor.close();
- mAdapter.setSuggestionsCursor(null);
+ JoinContactListFragment fragment = new JoinContactListFragment();
+ fragment.setTargetContactId(mTargetContactId);
+ fragment.setOnContactPickerActionListener(new OnContactPickerActionListener() {
+ public void onPickContactAction(Uri contactUri) {
+ Intent intent = new Intent(null, contactUri);
+ setResult(RESULT_OK, intent);
+ finish();
}
- if (mAdapter.getSuggestionsCursorCount() == 0
- || !mAdapter.isJoinModeShowAllContacts()) {
- startQuery(getContactFilterUri(mListFragment.getQueryString()),
- CONTACTS_SUMMARY_PROJECTION,
- Contacts._ID + " != " + mTargetContactId
- + " AND " + ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1", null,
- getSortOrder(CONTACTS_SUMMARY_PROJECTION));
- return;
+ public void onSearchAllContactsAction(String string) {
}
- cursor = getShowAllContactsLabelCursor(CONTACTS_SUMMARY_PROJECTION);
- }
+ public void onShortcutIntentCreated(Intent intent) {
+ }
- super.onQueryComplete(cursor);
+ public void onCreateNewContactAction() {
+ }
+ });
+
+ FragmentTransaction transaction = openFragmentTransaction();
+ transaction.add(fragment, android.R.id.content);
+ transaction.commit();
}
}
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index 30eef5a..c1b90a5 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -164,18 +164,16 @@
return;
}
- if (data == null) {
- return;
- }
-
if (mEmptyView != null && (data == null || data.getCount() == 0)) {
prepareEmptyView();
}
mAdapter.changeCursor(data);
- showCount(data);
- completeRestoreInstanceState();
+ if (data != null) {
+ showCount(data);
+ completeRestoreInstanceState();
+ }
}
protected void reloadData() {
@@ -461,7 +459,9 @@
@Override
public void onDestroy() {
- mPhotoLoader.stop();
+ if (isPhotoLoaderEnabled()) {
+ mPhotoLoader.stop();
+ }
super.onDestroy();
}
diff --git a/src/com/android/contacts/list/ContactItemListAdapter.java b/src/com/android/contacts/list/ContactItemListAdapter.java
index 733edab..bfae731 100644
--- a/src/com/android/contacts/list/ContactItemListAdapter.java
+++ b/src/com/android/contacts/list/ContactItemListAdapter.java
@@ -652,11 +652,6 @@
return super.getCount();
}
- @Override
- protected int getCursorPosition(int position) {
- return getRealPosition(position);
- }
-
protected int getRealPosition(int pos) {
if (contactsListActivity.mShowNumberOfContacts) {
pos--;
diff --git a/src/com/android/contacts/list/ContactListAdapter.java b/src/com/android/contacts/list/ContactListAdapter.java
index e6fe10a..3dfde7d 100644
--- a/src/com/android/contacts/list/ContactListAdapter.java
+++ b/src/com/android/contacts/list/ContactListAdapter.java
@@ -147,10 +147,13 @@
return view;
}
- protected void bindSectionHeaderAndDivider(final ContactListItemView view, Cursor cursor) {
- final int position = cursor.getPosition();
+ protected void bindSectionHeaderAndDivider(ContactListItemView view, Cursor cursor) {
+ bindSectionHeaderAndDivider(view, cursor.getPosition());
+ }
+
+ protected void bindSectionHeaderAndDivider(ContactListItemView view, int position) {
final int section = getSectionForPosition(position);
- if (getPositionForSection(section) == position) {
+ if (section != -1 && getPositionForSection(section) == position) {
String title = (String)getSections()[section];
view.setSectionHeader(title);
} else {
diff --git a/src/com/android/contacts/list/DefaultContactListAdapter.java b/src/com/android/contacts/list/DefaultContactListAdapter.java
index 0a108d2..984e808 100644
--- a/src/com/android/contacts/list/DefaultContactListAdapter.java
+++ b/src/com/android/contacts/list/DefaultContactListAdapter.java
@@ -81,14 +81,6 @@
}
@Override
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- final ContactListItemView view = new ContactListItemView(context, null);
- view.setUnknownNameText(getUnknownNameText());
- view.setTextWithHighlightingFactory(getTextWithHighlightingFactory());
- return view;
- }
-
- @Override
public void bindView(View itemView, Context context, Cursor cursor) {
final ContactListItemView view = (ContactListItemView)itemView;
diff --git a/src/com/android/contacts/list/JoinContactListAdapter.java b/src/com/android/contacts/list/JoinContactListAdapter.java
index 58f1c97..26c2e22 100644
--- a/src/com/android/contacts/list/JoinContactListAdapter.java
+++ b/src/com/android/contacts/list/JoinContactListAdapter.java
@@ -15,49 +15,105 @@
*/
package com.android.contacts.list;
-import com.android.contacts.ContactsListActivity;
import com.android.contacts.R;
-import com.android.contacts.list.ContactItemListAdapter;
+import android.app.patterns.CursorLoader;
+import android.content.Context;
import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.net.Uri.Builder;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Contacts.AggregationSuggestions;
+import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
-public class JoinContactListAdapter extends ContactItemListAdapter {
- Cursor mSuggestionsCursor;
- int mSuggestionsCursorCount;
+public class JoinContactListAdapter extends ContactListAdapter {
+
+ /** Maximum number of suggestions shown for joining aggregates */
+ private static final int MAX_SUGGESTIONS = 4;
+
+ private Cursor mSuggestionsCursor;
+ private int mSuggestionsCursorCount;
+ private long mTargetContactId;
/**
* Determines whether we display a list item with the label
* "Show all contacts" or actually show all contacts
*/
- boolean mJoinModeShowAllContacts;
+ private boolean mAllContactsListShown;
- public JoinContactListAdapter(ContactsListActivity context) {
+ public JoinContactListAdapter(Context context) {
super(context);
+ setSectionHeaderDisplayEnabled(true);
}
- public boolean isJoinModeShowAllContacts() {
- return mJoinModeShowAllContacts;
+ public void setTargetContactId(long targetContactId) {
+ this.mTargetContactId = targetContactId;
}
- public void setJoinModeShowAllContacts(boolean flag) {
- mJoinModeShowAllContacts = flag;
+ @Override
+ public void configureLoader(CursorLoader cursorLoader) {
+ JoinContactLoader loader = (JoinContactLoader)cursorLoader;
+ loader.setLoadSuggestionsAndAllContacts(mAllContactsListShown);
+
+ Builder builder = Contacts.CONTENT_URI.buildUpon();
+ builder.appendEncodedPath(String.valueOf(mTargetContactId));
+ builder.appendEncodedPath(AggregationSuggestions.CONTENT_DIRECTORY);
+
+ String filter = getQueryString();
+ if (!TextUtils.isEmpty(filter)) {
+ builder.appendEncodedPath(Uri.encode(filter));
+ }
+
+ builder.appendQueryParameter("limit", String.valueOf(MAX_SUGGESTIONS));
+
+ loader.setSuggestionUri(builder.build());
+
+ // TODO simplify projection
+ loader.setProjection(PROJECTION);
+
+ if (mAllContactsListShown) {
+ loader.setUri(buildSectionIndexerUri(Contacts.CONTENT_URI));
+ loader.setSelection(Contacts.IN_VISIBLE_GROUP + "=1 AND " + Contacts._ID + "!=?");
+ loader.setSelectionArgs(new String[]{String.valueOf(mTargetContactId)});
+ if (getSortOrder() == ContactsContract.Preferences.SORT_ORDER_PRIMARY) {
+ loader.setSortOrder(Contacts.SORT_KEY_PRIMARY);
+ } else {
+ loader.setSortOrder(Contacts.SORT_KEY_ALTERNATIVE);
+ }
+ }
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ private boolean hasSuggestions() {
+ return mSuggestionsCursorCount != 0;
+ }
+
+ public boolean isAllContactsListShown() {
+ return mAllContactsListShown;
+ }
+
+ public void setAllContactsListShown(boolean flag) {
+ mAllContactsListShown = flag;
}
public void setSuggestionsCursor(Cursor cursor) {
- if (mSuggestionsCursor != null) {
- mSuggestionsCursor.close();
- }
mSuggestionsCursor = cursor;
mSuggestionsCursorCount = cursor == null ? 0 : cursor.getCount();
}
- private boolean isShowAllContactsItemPosition(int position) {
- return mJoinModeShowAllContacts
- && mSuggestionsCursorCount != 0 && position == mSuggestionsCursorCount + 2;
+ public boolean isShowAllContactsItemPosition(int position) {
+ return !mAllContactsListShown
+ && hasSuggestions() && position == mSuggestionsCursorCount + 2;
}
@Override
@@ -67,33 +123,32 @@
"this should only be called when the cursor is valid");
}
- if (isShowAllContactsItemPosition(position)) {
- return LayoutInflater.from(getContext()).
- inflate(R.layout.contacts_list_show_all_item, parent, false);
- }
-
- // Handle the separator specially
- int separatorId = getSeparatorId(position);
- if (separatorId != 0) {
- TextView view = (TextView) LayoutInflater.from(getContext()).
- inflate(R.layout.list_separator, parent, false);
- view.setText(separatorId);
- return view;
- }
-
- boolean showingSuggestion;
Cursor cursor;
- if (mSuggestionsCursorCount != 0 && position < mSuggestionsCursorCount + 2) {
- showingSuggestion = true;
- cursor = mSuggestionsCursor;
+ boolean showingSuggestion = false;
+ if (hasSuggestions()) {
+ if (position == 0) {
+ // First section: "suggestions"
+ TextView view = (TextView) inflate(R.layout.list_separator, parent);
+ view.setText(R.string.separatorJoinAggregateSuggestions);
+ return view;
+ } else if (position < mSuggestionsCursorCount + 1) {
+ showingSuggestion = true;
+ cursor = mSuggestionsCursor;
+ cursor.moveToPosition(position - 1);
+ } else if (position == mSuggestionsCursorCount + 1) {
+ // Second section: "all contacts"
+ TextView view = (TextView) inflate(R.layout.list_separator, parent);
+ view.setText(R.string.separatorJoinAggregateAll);
+ return view;
+ } else if (!mAllContactsListShown && position == mSuggestionsCursorCount + 2) {
+ return inflate(R.layout.contacts_list_show_all_item, parent);
+ } else {
+ cursor = mCursor;
+ cursor.moveToPosition(position - mSuggestionsCursorCount - 2);
+ }
} else {
- showingSuggestion = false;
cursor = mCursor;
- }
-
- int realPosition = getRealPosition(position);
- if (!cursor.moveToPosition(realPosition)) {
- throw new IllegalStateException("couldn't move cursor to position " + position);
+ cursor.moveToPosition(position);
}
boolean newView;
@@ -105,11 +160,35 @@
newView = false;
v = convertView;
}
- bindView(v, getContext(), cursor);
- bindSectionHeader(v, realPosition, !showingSuggestion);
+ bindView(position, v, cursor, showingSuggestion);
return v;
}
+ private View inflate(int layoutId, ViewGroup parent) {
+ return LayoutInflater.from(getContext()).inflate(layoutId, parent, false);
+ }
+
+ @Override
+ public void bindView(View view, Context context, Cursor cursor) {
+ // not used
+ }
+
+ public void bindView(int position, View itemView, Cursor cursor, boolean showingSuggestion) {
+ final ContactListItemView view = (ContactListItemView)itemView;
+ if (!showingSuggestion) {
+ bindSectionHeaderAndDivider(view, position);
+ }
+ bindPhoto(view, cursor);
+ bindName(view, cursor);
+ }
+
+ public Cursor getShowAllContactsLabelCursor() {
+ MatrixCursor matrixCursor = new MatrixCursor(PROJECTION);
+ Object[] row = new Object[PROJECTION.length];
+ matrixCursor.addRow(row);
+ return matrixCursor;
+ }
+
@Override
public void changeCursor(Cursor cursor) {
if (cursor == null) {
@@ -118,6 +197,7 @@
super.changeCursor(cursor);
}
+
@Override
public int getItemViewType(int position) {
if (isShowAllContactsItemPosition(position)) {
@@ -127,15 +207,28 @@
return super.getItemViewType(position);
}
- private int getSeparatorId(int position) {
- if (mSuggestionsCursorCount != 0) {
- if (position == 0) {
- return R.string.separatorJoinAggregateSuggestions;
- } else if (position == mSuggestionsCursorCount + 1) {
- return R.string.separatorJoinAggregateAll;
- }
+ @Override
+ public int getPositionForSection(int sectionIndex) {
+ if (mSuggestionsCursorCount == 0) {
+ return super.getPositionForSection(sectionIndex);
}
- return 0;
+
+ // Get section position in the full list
+ int position = super.getPositionForSection(sectionIndex);
+ return position + mSuggestionsCursorCount + 2;
+ }
+
+ @Override
+ public int getSectionForPosition(int position) {
+ if (mSuggestionsCursorCount == 0) {
+ return super.getSectionForPosition(position);
+ }
+
+ if (position < mSuggestionsCursorCount + 2) {
+ return -1;
+ }
+
+ return super.getSectionForPosition(position - mSuggestionsCursorCount - 2);
}
@Override
@@ -161,7 +254,7 @@
return 0;
}
int superCount = super.getCount();
- if (mSuggestionsCursorCount != 0) {
+ if (hasSuggestions()) {
// When showing suggestions, we have 2 additional list items: the "Suggestions"
// and "All contacts" headers.
return mSuggestionsCursorCount + superCount + 2;
@@ -174,52 +267,51 @@
}
@Override
- protected int getRealPosition(int pos) {
- if (mSuggestionsCursorCount != 0) {
+ public Object getItem(int pos) {
+ if (hasSuggestions()) {
// When showing suggestions, we have 2 additional list items: the "Suggestions"
// and "All contacts" separators.
- if (pos < mSuggestionsCursorCount + 2) {
- // We are in the upper partition (Suggestions). Adjusting for the "Suggestions"
- // separator.
- return pos - 1;
- } else {
- // We are in the lower partition (All contacts). Adjusting for the size
- // of the upper partition plus the two separators.
- return pos - mSuggestionsCursorCount - 2;
- }
- } else {
- // No separator, identity map
- return pos;
- }
- }
-
- @Override
- public Object getItem(int pos) {
- if (mSuggestionsCursorCount != 0 && pos <= mSuggestionsCursorCount) {
- mSuggestionsCursor.moveToPosition(getRealPosition(pos));
- return mSuggestionsCursor;
- } else {
- int realPosition = getRealPosition(pos);
- if (realPosition < 0) {
+ if (pos == 0) {
return null;
}
- return super.getItem(realPosition);
+ else if (pos < mSuggestionsCursorCount + 1) {
+ // We are in the upper partition (Suggestions). Adjusting for the "Suggestions"
+ // separator.
+ mSuggestionsCursor.moveToPosition(pos - 1);
+ return mSuggestionsCursor;
+ } else if (pos == mSuggestionsCursorCount + 1) {
+ // This is the "All contacts" separator
+ return null;
+ } else {
+ if (!isAllContactsListShown()) {
+ // This is the "Show all contacts" item
+ return null;
+ } else {
+ // We are in the lower partition (All contacts). Adjusting for the size
+ // of the upper partition plus the two separators.
+ mCursor.moveToPosition(pos - mSuggestionsCursorCount - 2);
+ return mCursor;
+ }
+ }
+ } else if (mCursor != null) {
+ // No separators
+ mCursor.moveToPosition(pos);
+ return mCursor;
+ } else {
+ return null;
}
}
@Override
public long getItemId(int pos) {
- if (mSuggestionsCursorCount != 0 && pos < mSuggestionsCursorCount + 2) {
- if (mSuggestionsCursor.moveToPosition(pos - 1)) {
- return mSuggestionsCursor.getLong(mRowIDColumn);
- } else {
- return 0;
- }
- }
- int realPosition = getRealPosition(pos);
- if (realPosition < 0) {
- return 0;
- }
- return super.getItemId(realPosition);
+ Cursor cursor = (Cursor)getItem(pos);
+ return cursor == null ? 0 : cursor.getLong(mRowIDColumn);
+ }
+
+ public Uri getContactUri(int position) {
+ Cursor cursor = (Cursor)getItem(position);
+ long contactId = cursor.getLong(CONTACT_ID_COLUMN_INDEX);
+ String lookupKey = cursor.getString(CONTACT_LOOKUP_KEY_COLUMN_INDEX);
+ return Contacts.getLookupUri(contactId, lookupKey);
}
}
\ No newline at end of file
diff --git a/src/com/android/contacts/list/JoinContactListFragment.java b/src/com/android/contacts/list/JoinContactListFragment.java
index 3693070..202ee67 100644
--- a/src/com/android/contacts/list/JoinContactListFragment.java
+++ b/src/com/android/contacts/list/JoinContactListFragment.java
@@ -15,25 +15,99 @@
*/
package com.android.contacts.list;
-import com.android.contacts.JoinContactActivity;
import com.android.contacts.R;
+import android.app.Activity;
+import android.app.patterns.CursorLoader;
+import android.app.patterns.Loader;
+import android.content.ContentUris;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.ContactsContract.Contacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.TextView;
/**
* Fragment for the Join Contact list.
*/
-public class JoinContactListFragment extends ContactEntryListFragment {
+public class JoinContactListFragment extends ContactEntryListFragment<JoinContactListAdapter> {
+
+ private static final int DISPLAY_NAME_LOADER = 1;
+
+ private OnContactPickerActionListener mListener;
+ private long mTargetContactId;
+ private boolean mAllContactsListShown = false;
+
+ public JoinContactListFragment() {
+ setPhotoLoaderEnabled(true);
+ setSectionHeaderDisplayEnabled(true);
+ }
+
+ public void setOnContactPickerActionListener(OnContactPickerActionListener listener) {
+ mListener = listener;
+ }
@Override
- public ContactEntryListAdapter createListAdapter() {
- JoinContactListAdapter adapter =
- new JoinContactListAdapter((JoinContactActivity)getActivity());
- adapter.setSectionHeaderDisplayEnabled(true);
- adapter.setDisplayPhotos(true);
- return adapter;
+ protected void onInitializeLoaders() {
+ super.onInitializeLoaders();
+ startLoading(DISPLAY_NAME_LOADER, null);
+ }
+
+ @Override
+ protected Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ if (id == DISPLAY_NAME_LOADER) {
+ // Loader for the display name of the target contact
+ return new CursorLoader(getActivity(),
+ ContentUris.withAppendedId(Contacts.CONTENT_URI, mTargetContactId),
+ new String[] {Contacts.DISPLAY_NAME}, null, null, null);
+ } else {
+ return new JoinContactLoader(getActivity());
+ }
+ }
+
+ @Override
+ protected void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ if (loader.getId() == DISPLAY_NAME_LOADER) {
+ if (data != null && data.moveToFirst()) {
+ showTargetContactName(data.getString(0));
+ }
+ } else {
+ JoinContactListAdapter adapter = getAdapter();
+ if (adapter.isAllContactsListShown()) {
+ Cursor suggestionsCursor = ((JoinContactLoader)loader).getSuggestionsCursor();
+ adapter.setSuggestionsCursor(suggestionsCursor);
+ super.onLoadFinished(loader, data);
+ } else {
+ adapter.setSuggestionsCursor(data);
+ super.onLoadFinished(loader, adapter.getShowAllContactsLabelCursor());
+ }
+ }
+ }
+
+ private void showTargetContactName(String displayName) {
+ Activity activity = getActivity();
+ TextView blurbView = (TextView)activity.findViewById(R.id.join_contact_blurb);
+ String blurb = activity.getString(R.string.blurbJoinContactDataWith, displayName);
+ blurbView.setText(blurb);
+ }
+
+ public void setTargetContactId(long targetContactId) {
+ mTargetContactId = targetContactId;
+ }
+
+ @Override
+ public JoinContactListAdapter createListAdapter() {
+ return new JoinContactListAdapter(getActivity());
+ }
+
+ @Override
+ protected void configureAdapter() {
+ super.configureAdapter();
+ JoinContactListAdapter adapter = getAdapter();
+ adapter.setAllContactsListShown(mAllContactsListShown);
+ adapter.setTargetContactId(mTargetContactId);
}
@Override
@@ -43,7 +117,12 @@
@Override
protected void onItemClick(int position, long id) {
- // TODO
- throw new UnsupportedOperationException();
+ JoinContactListAdapter adapter = getAdapter();
+ if (adapter.isShowAllContactsItemPosition(position)) {
+ mAllContactsListShown = true;
+ reloadData();
+ } else {
+ mListener.onPickContactAction(adapter.getContactUri(position));
+ }
}
}
diff --git a/src/com/android/contacts/list/JoinContactLoader.java b/src/com/android/contacts/list/JoinContactLoader.java
new file mode 100644
index 0000000..c15acb1
--- /dev/null
+++ b/src/com/android/contacts/list/JoinContactLoader.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2010 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.list;
+
+import android.app.patterns.CursorLoader;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+
+/**
+ * A specialized loader for the Join Contacts UI. It executes up to two queries:
+ * join suggestions and (optionally) the full contact list.
+ */
+public class JoinContactLoader extends CursorLoader {
+
+ private boolean mLoadSuggestionsAndAllContact;
+ private String[] mProjection;
+ private Uri mSuggestionUri;
+ private MatrixCursor mCachedCursor;
+
+ public JoinContactLoader(Context context) {
+ super(context, null, null, null, null, null);
+ }
+
+ public void setSuggestionUri(Uri uri) {
+ this.mSuggestionUri = uri;
+ }
+
+ @Override
+ public void setProjection(String[] projection) {
+ super.setProjection(projection);
+ this.mProjection = projection;
+ }
+
+ public Cursor getSuggestionsCursor() {
+ return mCachedCursor;
+ }
+
+ @Override
+ protected Cursor loadInBackground() {
+ if (mLoadSuggestionsAndAllContact) {
+ // First execute the suggestions query, then call super.loadInBackground
+ // to load the entire list
+ mCachedCursor = loadSuggestions();
+ return super.loadInBackground();
+ } else {
+ // Use the default behavior of the super.loadInBackground to load join
+ // suggestions only
+ setUri(mSuggestionUri);
+ setSelection(null);
+ setSelectionArgs(null);
+ setSortOrder(null);
+ return super.loadInBackground();
+ }
+ }
+
+ /**
+ * Loads join suggestions into a MatrixCursor.
+ */
+ private MatrixCursor loadSuggestions() {
+ Cursor cursor = getContext().getContentResolver().query(mSuggestionUri, mProjection,
+ null, null, null);
+ try {
+ MatrixCursor matrix = new MatrixCursor(mProjection);
+ Object[] row = new Object[mProjection.length];
+ while (cursor.moveToNext()) {
+ for (int i = 0; i < row.length; i++) {
+ row[i] = cursor.getString(i);
+ }
+ matrix.addRow(row);
+ }
+ return matrix;
+ } finally {
+ cursor.close();
+ }
+ }
+
+ public void setLoadSuggestionsAndAllContacts(boolean flag) {
+ mLoadSuggestionsAndAllContact = flag;
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/contacts/list/StrequentContactListAdapter.java b/src/com/android/contacts/list/StrequentContactListAdapter.java
index 239f804..cef0604 100644
--- a/src/com/android/contacts/list/StrequentContactListAdapter.java
+++ b/src/com/android/contacts/list/StrequentContactListAdapter.java
@@ -147,9 +147,7 @@
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
- final ContactListItemView view = new ContactListItemView(context, null);
- view.setUnknownNameText(getUnknownNameText());
- view.setTextWithHighlightingFactory(getTextWithHighlightingFactory());
+ ContactListItemView view = (ContactListItemView)super.newView(context, cursor, parent);
view.setOnCallButtonClickListener(mCallButtonListener);
return view;
}
diff --git a/src/com/android/contacts/widget/PinnedHeaderListAdapter.java b/src/com/android/contacts/widget/PinnedHeaderListAdapter.java
index db99e14..7492de1 100644
--- a/src/com/android/contacts/widget/PinnedHeaderListAdapter.java
+++ b/src/com/android/contacts/widget/PinnedHeaderListAdapter.java
@@ -64,16 +64,6 @@
mIndexer = indexer;
}
- /**
- * Maps an adapter position to the corresponding cursor position. Should not
- * be needed once we have switched to using header views and composite
- * list adapters.
- */
- @Deprecated
- protected int getCursorPosition(int position) {
- return position;
- }
-
public Object [] getSections() {
if (mIndexer == null) {
return new String[] { " " };
@@ -107,16 +97,15 @@
return PINNED_HEADER_GONE;
}
- int realPosition = getCursorPosition(position);
- if (realPosition < 0) {
+ // The header should get pushed up if the top item shown
+ // is the last item in a section for a particular letter.
+ int section = getSectionForPosition(position);
+ if (section == -1) {
return PINNED_HEADER_GONE;
}
- // The header should get pushed up if the top item shown
- // is the last item in a section for a particular letter.
- int section = getSectionForPosition(realPosition);
int nextSectionPosition = getPositionForSection(section + 1);
- if (nextSectionPosition != -1 && realPosition == nextSectionPosition - 1) {
+ if (nextSectionPosition != -1 && position == nextSectionPosition - 1) {
return PINNED_HEADER_PUSHED_UP;
}
@@ -144,8 +133,7 @@
header.setTag(cache);
}
- int realPosition = getCursorPosition(position);
- int section = getSectionForPosition(realPosition);
+ int section = getSectionForPosition(position);
String title = (String)mIndexer.getSections()[section];
cache.titleView.setText(title);