Merge "Implemented all missing functionality from Editor-Fragment (minus Statehandling)"
diff --git a/src/com/android/contacts/MultiplePhonePickerActivity.java b/src/com/android/contacts/MultiplePhonePickerActivity.java
index b554166..6b066a7 100644
--- a/src/com/android/contacts/MultiplePhonePickerActivity.java
+++ b/src/com/android/contacts/MultiplePhonePickerActivity.java
@@ -16,164 +16,71 @@
package com.android.contacts;
-import com.android.contacts.list.MultiplePhoneExtraAdapter;
-import com.android.contacts.list.MultiplePhonePickerAdapter;
-import com.android.contacts.list.MultiplePhonePickerItemView;
-import com.android.contacts.list.MultiplePhoneSelection;
+import com.android.contacts.list.MultiplePhonePickerFragment;
+import com.android.contacts.list.OnMultiplePhoneNumberPickerActionListener;
-import android.app.ProgressDialog;
-import android.content.ContentResolver;
-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.os.Bundle;
-import android.os.Handler;
import android.os.Parcelable;
import android.provider.ContactsContract.Intents;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.text.TextUtils;
-import android.util.SparseIntArray;
import android.view.Menu;
import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewStub;
-import android.view.View.OnClickListener;
-import android.view.animation.AnimationUtils;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.ListView;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
/**
* Displays of phone numbers and allows selection of multiple numbers.
*/
-public class MultiplePhonePickerActivity extends ContactsListActivity implements OnClickListener {
- /**
- * User selected phone number and id in MODE_PICK_MULTIPLE_PHONES mode.
- */
- public final MultiplePhoneSelection mUserSelection = new MultiplePhoneSelection(this);
-
- /**
- * The adapter for the phone numbers, used in MODE_PICK_MULTIPLE_PHONES mode.
- */
- public final MultiplePhoneExtraAdapter mPhoneNumberAdapter =
- new MultiplePhoneExtraAdapter(this, this, mUserSelection);
-
- private static int[] CHIP_COLOR_ARRAY = {
- R.drawable.appointment_indicator_leftside_1,
- R.drawable.appointment_indicator_leftside_2,
- R.drawable.appointment_indicator_leftside_3,
- R.drawable.appointment_indicator_leftside_4,
- R.drawable.appointment_indicator_leftside_5,
- R.drawable.appointment_indicator_leftside_6,
- R.drawable.appointment_indicator_leftside_7,
- R.drawable.appointment_indicator_leftside_8,
- R.drawable.appointment_indicator_leftside_9,
- R.drawable.appointment_indicator_leftside_10,
- R.drawable.appointment_indicator_leftside_11,
- R.drawable.appointment_indicator_leftside_12,
- R.drawable.appointment_indicator_leftside_13,
- R.drawable.appointment_indicator_leftside_14,
- R.drawable.appointment_indicator_leftside_15,
- R.drawable.appointment_indicator_leftside_16,
- R.drawable.appointment_indicator_leftside_17,
- R.drawable.appointment_indicator_leftside_18,
- R.drawable.appointment_indicator_leftside_19,
- R.drawable.appointment_indicator_leftside_20,
- R.drawable.appointment_indicator_leftside_21,
- };
-
- /**
- * This is the map from contact to color index.
- * A colored chip in MODE_PICK_MULTIPLE_PHONES mode is used to indicate the number of phone
- * numbers belong to one contact
- */
- SparseIntArray mContactColor = new SparseIntArray();
-
- /**
- * UI control of action panel in MODE_PICK_MULTIPLE_PHONES mode.
- */
- private View mFooterView;
+public class MultiplePhonePickerActivity extends Activity {
/**
* Display only selected recipients or not in MODE_PICK_MULTIPLE_PHONES mode
*/
- public boolean mShowSelectedOnly = false;
+ private boolean mShowSelectedOnly = false;
- public OnClickListener mCheckBoxClickerListener = new OnClickListener () {
- public void onClick(View v) {
- final MultiplePhonePickerItemView itemView =
- (MultiplePhonePickerItemView) v.getParent();
- if (itemView.phoneId != MultiplePhoneExtraAdapter.INVALID_PHONE_ID) {
- mUserSelection.setPhoneSelected(itemView.phoneId, ((CheckBox) v).isChecked());
- } else {
- mUserSelection.setPhoneSelected(itemView.phoneNumber,
- ((CheckBox) v).isChecked());
+ private MultiplePhonePickerFragment mListFragment;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mListFragment = new MultiplePhonePickerFragment();
+ mListFragment.setOnMultiplePhoneNumberPickerActionListener(
+ new OnMultiplePhoneNumberPickerActionListener() {
+
+ public void onPhoneNumbersSelectedAction(Uri[] dataUris) {
+ returnActivityResult(dataUris);
}
- updateWidgets(true);
- }
- };
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- initMultiPicker(getIntent());
+ public void onFinishAction() {
+ finish();
+ }
+ });
+
+ Parcelable[] extras = getIntent().getParcelableArrayExtra(Intents.EXTRA_PHONE_URIS);
+ mListFragment.setSelectedUris(extras);
+ FragmentTransaction transaction = openFragmentTransaction();
+ transaction.add(mListFragment, android.R.id.content);
+ transaction.commit();
}
@Override
- protected void onResume() {
- super.onResume();
-
- // TODO move this to onAttach of the corresponding fragment
- ListView listView = (ListView)findViewById(android.R.id.list);
- ((MultiplePhonePickerAdapter)listView.getAdapter()).setExtraAdapter(mPhoneNumberAdapter);
- ViewStub stub = (ViewStub)findViewById(R.id.footer_stub);
- if (stub != null) {
- View stubView = stub.inflate();
- mFooterView = stubView.findViewById(R.id.footer);
- mFooterView.setVisibility(View.GONE);
- Button doneButton = (Button) stubView.findViewById(R.id.done);
- doneButton.setOnClickListener(this);
- Button revertButton = (Button) stubView.findViewById(R.id.revert);
- revertButton.setOnClickListener(this);
- }
- }
-
- public void onClick(View v) {
- int id = v.getId();
- switch (id) {
- case R.id.done:
- setMultiPickerResult();
- finish();
- break;
- case R.id.revert:
- finish();
- break;
- }
+ public void onBackPressed() {
+ returnActivityResult(mListFragment.getSelectedUris());
+ super.onBackPressed();
}
@Override
protected void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(icicle);
- ListView listView = (ListView)findViewById(android.R.id.list);
- if (listView != null) {
- if (mUserSelection != null) {
- mUserSelection.saveInstanceState(icicle);
- }
- }
+ mListFragment.onSaveInstanceState(icicle);
}
@Override
protected void onRestoreInstanceState(Bundle icicle) {
super.onRestoreInstanceState(icicle);
- // Retrieve list state. This will be applied after the QueryHandler has run
- mUserSelection.restoreInstanceState(icicle);
+ mListFragment.onRestoreInstanceState(icicle);
}
@Override
@@ -185,6 +92,7 @@
return true;
}
+ /*
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (mShowSelectedOnly) {
@@ -234,7 +142,7 @@
}
return super.onOptionsItemSelected(item);
}
-
+*/
@Override
public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
boolean globalSearch) {
@@ -242,203 +150,72 @@
// if (mProviderStatus != ProviderStatus.STATUS_NORMAL) {
// return;
// }
-
- if (globalSearch) {
- super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
- } else {
- if (!mSearchMode && (mMode & MODE_MASK_NO_FILTER) == 0) {
- if ((mMode & MODE_MASK_PICKER) != 0) {
- Bundle extras = getIntent().getExtras();
- if (extras == null) {
- extras = new Bundle();
- }
- mUserSelection.fillSelectionForSearchMode(extras);
- ContactsSearchManager.startSearchForResult(this, initialQuery,
- SUBACTIVITY_FILTER, extras);
- } else {
- ContactsSearchManager.startSearch(this, initialQuery);
- }
- }
- }
+//
+// if (globalSearch) {
+// super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
+// } else {
+// if (!mSearchMode && (mMode & MODE_MASK_NO_FILTER) == 0) {
+// if ((mMode & MODE_MASK_PICKER) != 0) {
+// Bundle extras = getIntent().getExtras();
+// if (extras == null) {
+// extras = new Bundle();
+// }
+// mUserSelection.fillSelectionForSearchMode(extras);
+// ContactsSearchManager.startSearchForResult(this, initialQuery,
+// SUBACTIVITY_FILTER, extras);
+// } else {
+// ContactsSearchManager.startSearch(this, initialQuery);
+// }
+// }
+// }
}
- @Override
- public void onBackPressed() {
- setMultiPickerResult();
- super.onBackPressed();
- }
+// @Override
+// protected void startQuery(Uri uri, String[] projection) {
+// // Filter unknown phone numbers first.
+// mPhoneNumberAdapter.doFilter(null, mShowSelectedOnly);
+// if (mShowSelectedOnly) {
+// StringBuilder idSetBuilder = new StringBuilder();
+// Iterator<Long> itr = mUserSelection.getSelectedPhonIds();
+// if (itr.hasNext()) {
+// idSetBuilder.append(Long.toString(itr.next()));
+// }
+// while (itr.hasNext()) {
+// idSetBuilder.append(',');
+// idSetBuilder.append(Long.toString(itr.next()));
+// }
+// String whereClause = Phone._ID + " IN (" + idSetBuilder.toString() + ")";
+// mQueryHandler.startQuery(QUERY_TOKEN, null, uri, projection, whereClause, null,
+// getSortOrder(projection));
+// } else {
+// mQueryHandler.startQuery(QUERY_TOKEN, null, uri,
+// projection, CLAUSE_ONLY_VISIBLE, null, getSortOrder(projection));
+// }
+// }
- @Override
- protected void startQuery(Uri uri, String[] projection) {
- // Filter unknown phone numbers first.
- mPhoneNumberAdapter.doFilter(null, mShowSelectedOnly);
- if (mShowSelectedOnly) {
- StringBuilder idSetBuilder = new StringBuilder();
- Iterator<Long> itr = mUserSelection.getSelectedPhonIds();
- if (itr.hasNext()) {
- idSetBuilder.append(Long.toString(itr.next()));
- }
- while (itr.hasNext()) {
- idSetBuilder.append(',');
- idSetBuilder.append(Long.toString(itr.next()));
- }
- String whereClause = Phone._ID + " IN (" + idSetBuilder.toString() + ")";
- mQueryHandler.startQuery(QUERY_TOKEN, null, uri, projection, whereClause, null,
- getSortOrder(projection));
- } else {
- mQueryHandler.startQuery(QUERY_TOKEN, null, uri,
- projection, CLAUSE_ONLY_VISIBLE, null, getSortOrder(projection));
- }
- }
+// @Override
+// public Cursor doFilter(String filter) {
+// String[] projection = getProjectionForQuery();
+// if (mSearchMode && TextUtils.isEmpty(mListFragment.getQueryString())) {
+// return new MatrixCursor(projection);
+// }
+//
+// final ContentResolver resolver = getContentResolver();
+// // Filter phone numbers as well.
+// mPhoneNumberAdapter.doFilter(filter, mShowSelectedOnly);
+//
+// Uri uri = getUriToQuery();
+// if (!TextUtils.isEmpty(filter)) {
+// uri = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, Uri.encode(filter));
+// }
+// return resolver.query(uri, projection, CLAUSE_ONLY_VISIBLE, null, getSortOrder(projection));
+// }
- @Override
- public Cursor doFilter(String filter) {
- String[] projection = getProjectionForQuery();
- if (mSearchMode && TextUtils.isEmpty(mListFragment.getQueryString())) {
- return new MatrixCursor(projection);
- }
-
- final ContentResolver resolver = getContentResolver();
- // Filter phone numbers as well.
- mPhoneNumberAdapter.doFilter(filter, mShowSelectedOnly);
-
- Uri uri = getUriToQuery();
- if (!TextUtils.isEmpty(filter)) {
- uri = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, Uri.encode(filter));
- }
- return resolver.query(uri, projection, CLAUSE_ONLY_VISIBLE, null, getSortOrder(projection));
- }
-
- private void initMultiPicker(final Intent intent) {
- final Handler handler = new Handler();
- // TODO : Shall we still show the progressDialog in search mode.
- final ProgressDialog progressDialog = new ProgressDialog(this);
- progressDialog.setMessage(getText(R.string.adding_recipients));
- progressDialog.setIndeterminate(true);
- progressDialog.setCancelable(false);
-
- final Runnable showProgress = new Runnable() {
- public void run() {
- progressDialog.show();
- }
- };
- handler.postDelayed(showProgress, 1);
-
- new Thread(new Runnable() {
- public void run() {
- try {
- loadSelectionFromIntent(intent);
- } finally {
- handler.removeCallbacks(showProgress);
- progressDialog.dismiss();
- }
- final Runnable populateWorker = new Runnable() {
- public void run() {
- if (mAdapter != null) {
- mAdapter.notifyDataSetChanged();
- }
- updateWidgets(false);
- }
- };
- handler.post(populateWorker);
- }
- }).start();
- }
-
- private void getPhoneNumbersOrIdsFromURIs(final Parcelable[] uris,
- final List<String> phoneNumbers, final List<Long> phoneIds) {
- if (uris != null) {
- for (Parcelable paracelable : uris) {
- Uri uri = (Uri) paracelable;
- if (uri == null) continue;
- String scheme = uri.getScheme();
- if (phoneNumbers != null && "tel".equals(scheme)) {
- phoneNumbers.add(uri.getSchemeSpecificPart());
- } else if (phoneIds != null && "content".equals(scheme)) {
- phoneIds.add(ContentUris.parseId(uri));
- }
- }
- }
- }
-
- private void loadSelectionFromIntent(Intent intent) {
- Parcelable[] uris = intent.getParcelableArrayExtra(Intents.EXTRA_PHONE_URIS);
- ArrayList<String> phoneNumbers = new ArrayList<String>();
- ArrayList<Long> phoneIds = new ArrayList<Long>();
- ArrayList<String> selectedPhoneNumbers = null;
- if (mSearchMode) {
- // All selection will be read from EXTRA_SELECTION
- getPhoneNumbersOrIdsFromURIs(uris, phoneNumbers, null);
- uris = intent.getParcelableArrayExtra(MultiplePhoneSelection.EXTRA_SELECTION);
- if (uris != null) {
- selectedPhoneNumbers = new ArrayList<String>();
- getPhoneNumbersOrIdsFromURIs(uris, selectedPhoneNumbers, phoneIds);
- }
- } else {
- getPhoneNumbersOrIdsFromURIs(uris, phoneNumbers, phoneIds);
- selectedPhoneNumbers = phoneNumbers;
- }
- mPhoneNumberAdapter.setPhoneNumbers(phoneNumbers);
- mUserSelection.setSelection(selectedPhoneNumbers, phoneIds);
- }
-
- private void setMultiPickerResult() {
- setResult(RESULT_OK, mUserSelection.createSelectionIntent());
- }
-
- /**
- * Go through the cursor and assign the chip color to contact who has more than one phone
- * numbers.
- * Assume the cursor is sorted by CONTACT_ID.
- */
- public void updateChipColor(Cursor cursor) {
- if (cursor == null || cursor.getCount() == 0) {
- return;
- }
- mContactColor.clear();
- int backupPos = cursor.getPosition();
- cursor.moveToFirst();
- int color = 0;
- long prevContactId = cursor.getLong(PHONE_CONTACT_ID_COLUMN_INDEX);
- while (cursor.moveToNext()) {
- long contactId = cursor.getLong(PHONE_CONTACT_ID_COLUMN_INDEX);
- if (prevContactId == contactId) {
- if (mContactColor.indexOfKey(Long.valueOf(contactId).hashCode()) < 0) {
- mContactColor.put(Long.valueOf(contactId).hashCode(), CHIP_COLOR_ARRAY[color]);
- color++;
- if (color >= CHIP_COLOR_ARRAY.length) {
- color = 0;
- }
- }
- }
- prevContactId = contactId;
- }
- cursor.moveToPosition(backupPos);
- }
-
- /**
- * Get assigned chip color resource id for a given contact, 0 is returned if there is no mapped
- * resource.
- */
- public int getChipColor(long contactId) {
- return mContactColor.get(Long.valueOf(contactId).hashCode());
- }
-
- private void updateWidgets(boolean changed) {
- int selected = mUserSelection.selectedCount();
-
- if (selected >= 1) {
- final String format =
- getResources().getQuantityString(R.plurals.multiple_picker_title, selected);
- setTitle(String.format(format, selected));
- } else {
- setTitle(getString(R.string.contactsList));
- }
-
- if (changed && mFooterView.getVisibility() == View.GONE) {
- mFooterView.setVisibility(View.VISIBLE);
- mFooterView.startAnimation(AnimationUtils.loadAnimation(this, R.anim.footer_appear));
- }
+ public void returnActivityResult(Uri[] dataUris) {
+ Intent intent = new Intent();
+ intent.putExtra(Intents.EXTRA_PHONE_URIS, dataUris);
+ setResult(RESULT_OK, intent);
+ finish();
}
private void checkAll(boolean checked) {
diff --git a/src/com/android/contacts/list/ContactListItemView.java b/src/com/android/contacts/list/ContactListItemView.java
index dd9ca08..28444a4 100644
--- a/src/com/android/contacts/list/ContactListItemView.java
+++ b/src/com/android/contacts/list/ContactListItemView.java
@@ -188,9 +188,10 @@
mLine4Height = 0;
// Obtain the natural dimensions of the name text (we only care about height)
- mNameTextView.measure(0, 0);
-
- mLine1Height = mNameTextView.getMeasuredHeight();
+ if (isVisible(mNameTextView)) {
+ mNameTextView.measure(0, 0);
+ mLine1Height = mNameTextView.getMeasuredHeight();
+ }
if (isVisible(mPhoneticNameTextView)) {
mPhoneticNameTextView.measure(0, 0);
@@ -288,10 +289,12 @@
int totalTextHeight = mLine1Height + mLine2Height + mLine3Height + mLine4Height;
int textTopBound = (bottomBound + topBound - totalTextHeight) / 2;
- mNameTextView.layout(leftBound,
- textTopBound,
- rightBound,
- textTopBound + mLine1Height);
+ if (isVisible(mNameTextView)) {
+ mNameTextView.layout(leftBound,
+ textTopBound,
+ rightBound,
+ textTopBound + mLine1Height);
+ }
int dataLeftBound = leftBound;
if (isVisible(mPhoneticNameTextView)) {
diff --git a/src/com/android/contacts/list/JoinContactListAdapter.java b/src/com/android/contacts/list/JoinContactListAdapter.java
index 26c2e22..614e4e5 100644
--- a/src/com/android/contacts/list/JoinContactListAdapter.java
+++ b/src/com/android/contacts/list/JoinContactListAdapter.java
@@ -151,13 +151,10 @@
cursor.moveToPosition(position);
}
- boolean newView;
View v;
if (convertView == null || convertView.getTag() == null) {
- newView = true;
v = newView(getContext(), cursor, parent);
} else {
- newView = false;
v = convertView;
}
bindView(position, v, cursor, showingSuggestion);
diff --git a/src/com/android/contacts/list/MultiplePhoneExtraAdapter.java b/src/com/android/contacts/list/MultiplePhoneExtraAdapter.java
deleted file mode 100644
index 66548db..0000000
--- a/src/com/android/contacts/list/MultiplePhoneExtraAdapter.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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 com.android.contacts.MultiplePhonePickerActivity;
-import com.android.contacts.R;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.CheckBox;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class is the adapter for the phone numbers which may not be found in the contacts. It is
- * called in ContactItemListAdapter in MODE_PICK_MULTIPLE_PHONES mode and shouldn't be a adapter
- * for any View due to the missing implementation of getItem and getItemId.
- */
-public class MultiplePhoneExtraAdapter extends BaseAdapter {
-
- private final MultiplePhonePickerActivity mMultiplePhonePickerActivity;
-
- public static final long INVALID_PHONE_ID = -1;
-
- /** The initial phone numbers */
- private List<String> mPhoneNumbers;
-
- /** The phone numbers after the filtering */
- private ArrayList<String> mFilteredPhoneNumbers = new ArrayList<String>();
-
- private final Context mContext;
-
- private final MultiplePhoneSelection mSelection;
-
- public MultiplePhoneExtraAdapter(MultiplePhonePickerActivity multiplePhonePickerActivity,
- Context context, MultiplePhoneSelection selection) {
- mContext = context;
- mMultiplePhonePickerActivity = multiplePhonePickerActivity;
- mSelection = selection;
- }
-
- public void setPhoneNumbers(ArrayList<String> phoneNumbers) {
- if (phoneNumbers != null) {
- mFilteredPhoneNumbers.addAll(phoneNumbers);
- mPhoneNumbers = phoneNumbers;
- } else {
- mPhoneNumbers = new ArrayList<String>();
- }
- }
-
- public int getCount() {
- int filteredCount = mFilteredPhoneNumbers.size();
- if (filteredCount == 0) {
- return 0;
- }
- // Count on the separator
- return 1 + filteredCount;
- }
-
- public Object getItem(int position) {
- // This method is not used currently.
- throw new RuntimeException("This method is not implemented");
- }
-
- public long getItemId(int position) {
- // This method is not used currently.
- throw new RuntimeException("This method is not implemented");
- }
-
- /**
- * @return the initial phone numbers, the zero length array is returned when there is no
- * initial numbers.
- */
- public final List<String> getPhoneNumbers() {
- return mPhoneNumbers;
- }
-
- /**
- * @return the filtered phone numbers, the zero size ArrayList is returned when there is no
- * initial numbers.
- */
- public ArrayList<String> getFilteredPhoneNumbers() {
- return mFilteredPhoneNumbers;
- }
-
- public View getView(int position, View convertView, ViewGroup parent) {
- int viewCount = getCount();
- if (viewCount == 0) {
- return null;
- }
-
- int startPos = (this.mMultiplePhonePickerActivity.mMode &
- MultiplePhonePickerActivity.MODE_MASK_SHOW_NUMBER_OF_CONTACTS) != 0 ? 1 : 0;
-
- // Separator
- if (position == startPos) {
- TextView view;
- if (convertView != null && convertView instanceof TextView) {
- view = (TextView) convertView;
- } else {
- LayoutInflater inflater =
- (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- view = (TextView) inflater.inflate(R.layout.list_separator, parent, false);
- }
- view.setText(R.string.unknown_contacts_separator);
- return view;
- }
- // PhoneNumbers start from position of startPos + 1
- if (position >= startPos + 1 && position < startPos + viewCount) {
- View view;
- if (convertView != null) {
- view = convertView;
- } else {
- view = this.mMultiplePhonePickerActivity.mAdapter.newView(mContext, null, parent);
- }
- bindView(view, mFilteredPhoneNumbers.get(position - 1 - startPos));
- return view;
- }
- return null;
- }
-
- @Override
- public int getItemViewType(int position) {
- int startPos = (this.mMultiplePhonePickerActivity.mMode &
- MultiplePhonePickerActivity.MODE_MASK_SHOW_NUMBER_OF_CONTACTS) != 0 ? 1 : 0;
-
- return position == startPos ? IGNORE_ITEM_VIEW_TYPE : super.getItemViewType(position);
- }
-
- private void bindView(View view, final String label) {
- MultiplePhonePickerItemView itemView = (MultiplePhonePickerItemView) view;
- itemView.setDividerVisible(true);
- itemView.setSectionHeader(null);
- itemView.setLabel(null);
- itemView.setData(null, 0);
- itemView.removePhotoView();
-
- itemView.getNameTextView().setText(label);
- CheckBox checkBox = itemView.getCheckBoxView();
- checkBox.setChecked(mSelection.isSelected(label));
- itemView.getChipView().setBackgroundResource(0);
- itemView.phoneId = INVALID_PHONE_ID;
- itemView.phoneNumber = label;
- }
-
- public void doFilter(final String constraint, boolean selectedOnly) {
- if (mPhoneNumbers == null) {
- return;
- }
- mFilteredPhoneNumbers.clear();
- for (String number : mPhoneNumbers) {
- if (selectedOnly && !mSelection.isSelected(number) ||
- !TextUtils.isEmpty(constraint) && !number.startsWith(constraint)) {
- continue;
- }
- mFilteredPhoneNumbers.add(number);
- }
- }
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/list/MultiplePhonePickerAdapter.java b/src/com/android/contacts/list/MultiplePhonePickerAdapter.java
index 11109d2..16ec183 100644
--- a/src/com/android/contacts/list/MultiplePhonePickerAdapter.java
+++ b/src/com/android/contacts/list/MultiplePhonePickerAdapter.java
@@ -15,175 +15,309 @@
*/
package com.android.contacts.list;
-import com.android.contacts.ContactsListActivity;
-import com.android.contacts.MultiplePhonePickerActivity;
+import com.android.contacts.R;
+import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
-import android.provider.ContactsContract.Contacts;
+import android.net.Uri;
import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.text.TextUtils;
+import android.util.SparseIntArray;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
-import android.widget.ImageView;
-import android.widget.QuickContactBadge;
-import android.widget.TextView;
-public class MultiplePhonePickerAdapter extends ContactItemListAdapter {
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
- private final MultiplePhonePickerActivity mMultiplePhonePickerActivity;
- private MultiplePhoneExtraAdapter mExtraAdapter;
+/**
+ * List adapter for the multiple phone picker.
+ */
+public class MultiplePhonePickerAdapter extends PhoneNumberListAdapter {
- public MultiplePhonePickerAdapter(MultiplePhonePickerActivity multiplePhonePickerActivity) {
- super(multiplePhonePickerActivity);
- this.mMultiplePhonePickerActivity = multiplePhonePickerActivity;
+ public interface OnSelectionChangeListener {
+ void onSelectionChange();
}
- public void setExtraAdapter(MultiplePhoneExtraAdapter extraAdapter) {
- mExtraAdapter = extraAdapter;
+ private static final int[] CHIP_COLOR_ARRAY = {
+ R.drawable.appointment_indicator_leftside_1,
+ R.drawable.appointment_indicator_leftside_2,
+ R.drawable.appointment_indicator_leftside_3,
+ R.drawable.appointment_indicator_leftside_4,
+ R.drawable.appointment_indicator_leftside_5,
+ R.drawable.appointment_indicator_leftside_6,
+ R.drawable.appointment_indicator_leftside_7,
+ R.drawable.appointment_indicator_leftside_8,
+ R.drawable.appointment_indicator_leftside_9,
+ R.drawable.appointment_indicator_leftside_10,
+ R.drawable.appointment_indicator_leftside_11,
+ R.drawable.appointment_indicator_leftside_12,
+ R.drawable.appointment_indicator_leftside_13,
+ R.drawable.appointment_indicator_leftside_14,
+ R.drawable.appointment_indicator_leftside_15,
+ R.drawable.appointment_indicator_leftside_16,
+ R.drawable.appointment_indicator_leftside_17,
+ R.drawable.appointment_indicator_leftside_18,
+ R.drawable.appointment_indicator_leftside_19,
+ R.drawable.appointment_indicator_leftside_20,
+ R.drawable.appointment_indicator_leftside_21,
+ };
+
+ public static final long INVALID_PHONE_ID = -1;
+
+ /** The phone numbers */
+ private ArrayList<String> mPhoneNumbers = new ArrayList<String>();
+
+ /** The selected phone numbers in the PhoneNumberAdapter */
+ private HashSet<String> mSelectedPhoneNumbers = new HashSet<String>();
+
+ /** The phone numbers after the filtering */
+ private ArrayList<String> mFilteredPhoneNumbers = new ArrayList<String>();
+
+ /** The PHONE_ID of selected number in user contacts*/
+ private HashSet<Long> mSelectedPhoneIds = new HashSet<Long>();
+
+ private boolean mSelectionChanged;
+
+ private OnSelectionChangeListener mSelectionChangeListener;
+
+ /**
+ * This is a map from contact ID to color index. A colored chip is used to
+ * indicate the number of phone numbers belong to one contact
+ */
+ private SparseIntArray mContactColor = new SparseIntArray();
+
+ public MultiplePhonePickerAdapter(Context context) {
+ super(context);
+ }
+
+ public void setOnSelectionChangeListener(OnSelectionChangeListener listener) {
+ this.mSelectionChangeListener = listener;
+ }
+
+ public void setPhoneNumbers(ArrayList<String> phoneNumbers) {
+ mPhoneNumbers.clear();
+ mPhoneNumbers.addAll(phoneNumbers);
+ }
+
+ public int getSelectedCount() {
+ return mSelectedPhoneNumbers.size() + mSelectedPhoneIds.size();
+ }
+
+ public Uri[] getSelectedUris() {
+ Uri[] uris = new Uri[mSelectedPhoneNumbers.size() + mSelectedPhoneIds.size()];
+ int count = mPhoneNumbers.size();
+ int index = 0;
+ for (int i = 0; i < count; i++) {
+ String phoneNumber = mPhoneNumbers.get(i);
+ if (isSelected(phoneNumber)) {
+ uris[index++] = Uri.parse("tel:" + phoneNumber);
+ }
+ }
+ for (Long contactId : mSelectedPhoneIds) {
+ uris[index++] = ContentUris.withAppendedId(Phone.CONTENT_URI, contactId);
+ }
+ return uris;
+ }
+
+ public void setSelectedUris(Uri[] uris) {
+ mSelectedPhoneNumbers.clear();
+ mSelectedPhoneIds.clear();
+ if (uris != null) {
+ for (Uri uri : uris) {
+ String scheme = uri.getScheme();
+ if ("tel".equals(scheme)) {
+ String phoneNumber = uri.getSchemeSpecificPart();
+ if (!mPhoneNumbers.contains(phoneNumber)) {
+ mPhoneNumbers.add(phoneNumber);
+ }
+ mSelectedPhoneNumbers.add(phoneNumber);
+ } else if ("content".equals(scheme)) {
+ mSelectedPhoneIds.add(ContentUris.parseId(uri));
+ }
+ }
+ }
+ mFilteredPhoneNumbers.clear();
+ mFilteredPhoneNumbers.addAll(mPhoneNumbers);
+ }
+
+ public void toggleSelection(int position) {
+ if (position < mFilteredPhoneNumbers.size()) {
+ String phoneNumber = mPhoneNumbers.get(position);
+ setPhoneSelected(phoneNumber, !isSelected(phoneNumber));
+ } else {
+ Cursor cursor = getCursor();
+ cursor.moveToPosition(position - mFilteredPhoneNumbers.size());
+ long phoneId = cursor.getLong(PHONE_ID_COLUMN_INDEX);
+ setPhoneSelected(phoneId, !isSelected(phoneId));
+ }
+ notifyDataSetChanged();
+ }
+
+ public boolean isSelectionChanged() {
+ return mSelectionChanged;
+ }
+
+ public void setSelectionChanged(boolean flag) {
+ mSelectionChanged = flag;
+ if (mSelectionChangeListener != null) {
+ mSelectionChangeListener.onSelectionChange();
+ }
+ }
+
+ public void setPhoneSelected(final String phoneNumber, boolean selected) {
+ if (!TextUtils.isEmpty(phoneNumber)) {
+ if (selected) {
+ mSelectedPhoneNumbers.add(phoneNumber);
+ } else {
+ mSelectedPhoneNumbers.remove(phoneNumber);
+ }
+ }
+ setSelectionChanged(true);
+ }
+
+ public void setPhoneSelected(long phoneId, boolean selected) {
+ if (selected) {
+ mSelectedPhoneIds.add(phoneId);
+ } else {
+ mSelectedPhoneIds.remove(phoneId);
+ }
+ setSelectionChanged(true);
+ }
+
+ public boolean isSelected(long phoneId) {
+ return mSelectedPhoneIds.contains(phoneId);
+ }
+
+ public boolean isSelected(final String phoneNumber) {
+ return mSelectedPhoneNumbers.contains(phoneNumber);
+ }
+
+ public void setAllPhonesSelected(boolean selected) {
+// if (selected) {
+// Cursor cursor = this.mMultiplePhoneSelectionActivity.mAdapter.getCursor();
+// if (cursor != null) {
+// int backupPos = cursor.getPosition();
+// cursor.moveToPosition(-1);
+// while (cursor.moveToNext()) {
+// setPhoneSelected(cursor
+// .getLong(MultiplePhonePickerActivity.PHONE_ID_COLUMN_INDEX), true);
+// }
+// cursor.moveToPosition(backupPos);
+// }
+// for (String number : this.mMultiplePhoneSelectionActivity.mPhoneNumberAdapter
+// .getFilteredPhoneNumbers()) {
+// setPhoneSelected(number, true);
+// }
+// } else {
+// mSelectedPhoneIds.clear();
+// mSelectedPhoneNumbers.clear();
+// }
+ }
+
+ public boolean isAllSelected() {
+ return false;
+// return selectedCount() == this.mMultiplePhoneSelectionActivity.mPhoneNumberAdapter
+// .getFilteredPhoneNumbers().size()
+// + this.mMultiplePhoneSelectionActivity.mAdapter.getCount();
+ }
+
+ public Iterator<Long> getSelectedPhoneIds() {
+ return mSelectedPhoneIds.iterator();
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 2;
}
@Override
public int getItemViewType(int position) {
- if (position == 0 && mMultiplePhonePickerActivity.mShowNumberOfContacts) {
- return IGNORE_ITEM_VIEW_TYPE;
- }
-
- if (position < mExtraAdapter.getCount()) {
- return mExtraAdapter.getItemViewType(position);
- }
-
- return super.getItemViewType(position);
+ return position < mPhoneNumbers.size() ? 0 : 1;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- if (position == 0 && mMultiplePhonePickerActivity.mShowNumberOfContacts) {
- return super.getView(position, convertView, parent);
+ View view;
+ if (convertView == null || convertView.getTag() == null) {
+ view = newView(getContext(), null, parent);
+ } else {
+ view = convertView;
}
- if (position < mExtraAdapter.getCount()) {
- return mExtraAdapter.getView(position,
- convertView, parent);
+ boolean showingSuggestion = false;
+
+ if (position < mFilteredPhoneNumbers.size()) {
+ bindExtraPhoneView(view, position);
+ } else {
+ Cursor cursor = getCursor();
+ cursor.moveToPosition(position - mFilteredPhoneNumbers.size());
+ bindView(view, getContext(), cursor);
}
- return super.getView(position, convertView, parent);
+ return view;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final MultiplePhonePickerItemView view = new MultiplePhonePickerItemView(context, null);
- view.setOnCallButtonClickListener(mMultiplePhonePickerActivity);
- view.setOnCheckBoxClickListener(mMultiplePhonePickerActivity.mCheckBoxClickerListener);
+ view.setUnknownNameText(getUnknownNameText());
+ view.setTextWithHighlightingFactory(getTextWithHighlightingFactory());
return view;
}
+ private void bindExtraPhoneView(View itemView, int position) {
+ final MultiplePhonePickerItemView view = (MultiplePhonePickerItemView)itemView;
+ String phoneNumber = mFilteredPhoneNumbers.get(position);
+ view.getNameTextView().setText(phoneNumber);
+ CheckBox checkBox = view.getCheckBoxView();
+ checkBox.setChecked(isSelected(phoneNumber));
+ view.phoneId = INVALID_PHONE_ID;
+ view.phoneNumber = phoneNumber;
+ }
+
@Override
public void bindView(View itemView, Context context, Cursor cursor) {
+ super.bindView(itemView, context, cursor);
+
final MultiplePhonePickerItemView view = (MultiplePhonePickerItemView)itemView;
-
- int typeColumnIndex;
- int dataColumnIndex;
- int labelColumnIndex;
- int defaultType;
- int nameColumnIndex;
- int phoneticNameColumnIndex;
- int photoColumnIndex = ContactsListActivity.SUMMARY_PHOTO_ID_COLUMN_INDEX;
- boolean displayAdditionalData = mDisplayAdditionalData;
- nameColumnIndex = ContactsListActivity.PHONE_DISPLAY_NAME_COLUMN_INDEX;
- phoneticNameColumnIndex = -1;
- dataColumnIndex = ContactsListActivity.PHONE_NUMBER_COLUMN_INDEX;
- typeColumnIndex = ContactsListActivity.PHONE_TYPE_COLUMN_INDEX;
- labelColumnIndex = ContactsListActivity.PHONE_LABEL_COLUMN_INDEX;
- defaultType = Phone.TYPE_HOME;
- photoColumnIndex = ContactsListActivity.PHONE_PHOTO_ID_COLUMN_INDEX;
-
- view.phoneId = Long.valueOf(cursor.getLong(ContactsListActivity.PHONE_ID_COLUMN_INDEX));
+ view.phoneId = Long.valueOf(cursor.getLong(PHONE_ID_COLUMN_INDEX));
CheckBox checkBox = view.getCheckBoxView();
- checkBox.setChecked(mMultiplePhonePickerActivity.mUserSelection.isSelected(view.phoneId));
- int color = mMultiplePhonePickerActivity.getChipColor(cursor
- .getLong(ContactsListActivity.PHONE_CONTACT_ID_COLUMN_INDEX));
- view.getChipView().setBackgroundResource(color);
+ checkBox.setChecked(isSelected(view.phoneId));
- // Set the name
- cursor.copyStringToBuffer(nameColumnIndex, view.nameBuffer);
- TextView nameView = view.getNameTextView();
- int size = view.nameBuffer.sizeCopied;
- if (size != 0) {
- nameView.setText(view.nameBuffer.data, 0, size);
- } else {
- nameView.setText(mUnknownNameText);
- }
-
- // Set the photo, if requested
- if (mDisplayPhotos) {
- boolean useQuickContact = false;
-
- long photoId = 0;
- if (!cursor.isNull(photoColumnIndex)) {
- photoId = cursor.getLong(photoColumnIndex);
- }
-
- ImageView viewToUse;
- if (useQuickContact) {
- // Build soft lookup reference
- final long contactId = cursor.getLong(ContactsListActivity.SUMMARY_ID_COLUMN_INDEX);
- final String lookupKey = cursor
- .getString(ContactsListActivity.SUMMARY_LOOKUP_KEY_COLUMN_INDEX);
- QuickContactBadge quickContact = view.getQuickContact();
- quickContact.assignContactUri(Contacts.getLookupUri(contactId, lookupKey));
- viewToUse = quickContact;
- } else {
- viewToUse = view.getPhotoView();
- }
-
- final int position = cursor.getPosition();
- getPhotoLoader().loadPhoto(viewToUse, photoId);
- }
-
- if (!displayAdditionalData) {
- if (phoneticNameColumnIndex != -1) {
-
- // Set the name
- cursor.copyStringToBuffer(phoneticNameColumnIndex, view.phoneticNameBuffer);
- int phoneticNameSize = view.phoneticNameBuffer.sizeCopied;
- if (phoneticNameSize != 0) {
- view.setLabel(view.phoneticNameBuffer.data, phoneticNameSize);
- } else {
- view.setLabel(null);
- }
- } else {
- view.setLabel(null);
- }
- return;
- }
-
- // Set the data.
- cursor.copyStringToBuffer(dataColumnIndex, view.dataBuffer);
-
- size = view.dataBuffer.sizeCopied;
- view.setData(view.dataBuffer.data, size);
-
- // Set the label.
- if (!cursor.isNull(typeColumnIndex)) {
- final int type = cursor.getInt(typeColumnIndex);
- final String label = cursor.getString(labelColumnIndex);
- view.setLabel(Phone.getTypeLabel(context.getResources(), type, label));
- } else {
- view.setLabel(null);
- }
+ long contactId = cursor.getLong(PHONE_CONTACT_ID_COLUMN_INDEX);
+ view.getChipView().setBackgroundResource(getChipColor(contactId));
}
- @Override
- public void changeCursor(Cursor cursor) {
- super.changeCursor(cursor);
- mMultiplePhonePickerActivity.updateChipColor(cursor);
+// @Override
+// protected void prepareEmptyView() {
+// mMultiplePhonePickerActivity.mEmptyView.show(mMultiplePhonePickerActivity.mSearchMode,
+// true, false, false, false, true, mMultiplePhonePickerActivity.mShowSelectedOnly);
+// }
+
+ /**
+ * Get assigned chip color resource id for a given contact, 0 is returned if there is no mapped
+ * resource.
+ */
+ public int getChipColor(long contactId) {
+ return mContactColor.get((int)contactId);
}
- @Override
- protected void prepareEmptyView() {
- mMultiplePhonePickerActivity.mEmptyView.show(mMultiplePhonePickerActivity.mSearchMode,
- true, false, false, false, true, mMultiplePhonePickerActivity.mShowSelectedOnly);
- }
+ // TODO filtering
+// public void doFilter(final String constraint, boolean selectedOnly) {
+// if (mPhoneNumbers == null) {
+// return;
+// }
+// mFilteredPhoneNumbers.clear();
+// for (String number : mPhoneNumbers) {
+// if (selectedOnly && !mSelection.isSelected(number) ||
+// !TextUtils.isEmpty(constraint) && !number.startsWith(constraint)) {
+// continue;
+// }
+// mFilteredPhoneNumbers.add(number);
+// }
+// }
@Override
public int getCount() {
@@ -191,13 +325,39 @@
return 0;
}
- int count = super.getCount();
- count += mExtraAdapter.getCount();
- return count;
+ return super.getCount() + mFilteredPhoneNumbers.size();
}
@Override
- protected int getRealPosition(int pos) {
- return pos - mExtraAdapter.getCount();
+ public void changeCursor(Cursor cursor) {
+ super.changeCursor(cursor);
+ updateChipColor(cursor);
+ }
+
+ /**
+ * Go through the cursor and assign the chip color to contact who has more
+ * than one phone numbers. Assume the cursor is clustered by CONTACT_ID.
+ */
+ public void updateChipColor(Cursor cursor) {
+ if (cursor == null || cursor.getCount() == 0) {
+ return;
+ }
+ mContactColor.clear();
+ cursor.moveToFirst();
+ int colorIndex = 0;
+ long prevContactId = cursor.getLong(PHONE_CONTACT_ID_COLUMN_INDEX);
+ while (cursor.moveToNext()) {
+ long contactId = cursor.getLong(PHONE_CONTACT_ID_COLUMN_INDEX);
+ if (prevContactId == contactId) {
+ if (mContactColor.indexOfKey((int)contactId) < 0) {
+ mContactColor.put((int)contactId, CHIP_COLOR_ARRAY[colorIndex]);
+ colorIndex++;
+ if (colorIndex >= CHIP_COLOR_ARRAY.length) {
+ colorIndex = 0;
+ }
+ }
+ }
+ prevContactId = contactId;
+ }
}
}
diff --git a/src/com/android/contacts/list/MultiplePhonePickerFragment.java b/src/com/android/contacts/list/MultiplePhonePickerFragment.java
index a38c0ec..dcf62d7 100644
--- a/src/com/android/contacts/list/MultiplePhonePickerFragment.java
+++ b/src/com/android/contacts/list/MultiplePhonePickerFragment.java
@@ -15,35 +15,165 @@
*/
package com.android.contacts.list;
-import com.android.contacts.MultiplePhonePickerActivity;
import com.android.contacts.R;
+import com.android.contacts.list.MultiplePhonePickerAdapter.OnSelectionChangeListener;
+import android.app.Activity;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewStub;
+import android.view.View.OnClickListener;
+import android.view.animation.AnimationUtils;
+import android.widget.Button;
/**
* Fragment for the multiple phone picker.
*/
-public class MultiplePhonePickerFragment extends ContactEntryListFragment {
+public class MultiplePhonePickerFragment
+ extends ContactEntryListFragment<MultiplePhonePickerAdapter>
+ implements OnClickListener, OnSelectionChangeListener {
+
+ private static final String SELECTION_EXTRA_KEY = "selection";
+ private static final String SELECTION_CHANGED_EXTRA_KEY = "selectionChanged";
+
+ private OnMultiplePhoneNumberPickerActionListener mListener;
+
+ /**
+ * UI control of action panel in MODE_PICK_MULTIPLE_PHONES mode.
+ */
+ private View mFooterView;
+
+ private Uri[] mSelectedUris;
+ private boolean mSelectionChanged;
+
+ public MultiplePhonePickerFragment() {
+ setSectionHeaderDisplayEnabled(false);
+ setPhotoLoaderEnabled(true);
+ }
+
+ public void setOnMultiplePhoneNumberPickerActionListener(
+ OnMultiplePhoneNumberPickerActionListener listener) {
+ mListener = listener;
+ }
+
+ public Uri[] getSelectedUris() {
+ return getAdapter().getSelectedUris();
+ }
+
+ public void setSelectedUris(Parcelable[] extras) {
+ Uri[] uris = new Uri[extras == null ? 0 : extras.length];
+ if (extras != null) {
+ for (int i = 0; i < extras.length; i++) {
+ uris[i] = (Uri)extras[i];
+ }
+ }
+ setSelectedUris(uris);
+ }
+
+ public void setSelectedUris(Uri[] uris) {
+ mSelectedUris = uris;
+ MultiplePhonePickerAdapter adapter = getAdapter();
+ if (adapter != null) {
+ adapter.setSelectedUris(uris);
+ }
+ }
@Override
- public ContactEntryListAdapter createListAdapter() {
- MultiplePhonePickerAdapter adapter =
- new MultiplePhonePickerAdapter((MultiplePhonePickerActivity)getActivity());
- adapter.setSectionHeaderDisplayEnabled(true);
- adapter.setDisplayPhotos(true);
- return adapter;
+ protected MultiplePhonePickerAdapter createListAdapter() {
+ return new MultiplePhonePickerAdapter(getActivity());
+ }
+
+ @Override
+ protected void configureAdapter() {
+ super.configureAdapter();
+ MultiplePhonePickerAdapter adapter = getAdapter();
+ adapter.setSelectedUris(mSelectedUris);
+ adapter.setSelectionChanged(mSelectionChanged);
+ adapter.setOnSelectionChangeListener(this);
}
@Override
protected View inflateView(LayoutInflater inflater, ViewGroup container) {
- return inflater.inflate(R.layout.contacts_list_content, null);
+ View view = inflater.inflate(R.layout.contacts_list_content, null);
+ ViewStub stub = (ViewStub)view.findViewById(R.id.footer_stub);
+ if (stub != null) {
+ View stubView = stub.inflate();
+ mFooterView = stubView.findViewById(R.id.footer);
+ mFooterView.setVisibility(View.GONE);
+ Button doneButton = (Button) stubView.findViewById(R.id.done);
+ doneButton.setOnClickListener(this);
+ Button revertButton = (Button) stubView.findViewById(R.id.revert);
+ revertButton.setOnClickListener(this);
+ }
+ return view;
}
@Override
protected void onItemClick(int position, long id) {
- // TODO
- throw new UnsupportedOperationException();
+ getAdapter().toggleSelection(position);
+ }
+
+ public void onClick(View v) {
+ int id = v.getId();
+ switch (id) {
+ case R.id.done:
+ mListener.onPhoneNumbersSelectedAction(getAdapter().getSelectedUris());
+ break;
+ case R.id.revert:
+ mListener.onFinishAction();
+ break;
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateWidgets();
+ }
+
+ public void onSelectionChange() {
+ updateWidgets();
+ }
+
+ private void updateWidgets() {
+ int selected = getAdapter().getSelectedCount();
+
+ Activity context = getActivity();
+ if (selected >= 1) {
+ final String format = context.getResources().getQuantityString(
+ R.plurals.multiple_picker_title, selected);
+
+ // TODO: turn this into a callback
+ context.setTitle(String.format(format, selected));
+ } else {
+ // TODO: turn this into a callback
+ context.setTitle(context.getString(R.string.contactsList));
+ }
+
+ if (getAdapter().isSelectionChanged() && mFooterView.getVisibility() == View.GONE) {
+ mFooterView.setVisibility(View.VISIBLE);
+ mFooterView.startAnimation(AnimationUtils.loadAnimation(context, R.anim.footer_appear));
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle icicle) {
+ super.onSaveInstanceState(icicle);
+ icicle.putParcelableArray(SELECTION_EXTRA_KEY, getAdapter().getSelectedUris());
+ icicle.putBoolean(SELECTION_CHANGED_EXTRA_KEY, getAdapter().isSelectionChanged());
+ }
+
+ @Override
+ public void onRestoreInstanceState(Bundle icicle) {
+ super.onRestoreInstanceState(icicle);
+ setSelectedUris(icicle.getParcelableArray(SELECTION_EXTRA_KEY));
+ mSelectionChanged = icicle.getBoolean(SELECTION_CHANGED_EXTRA_KEY, false);
+ if (getAdapter() != null) {
+ getAdapter().setSelectionChanged(mSelectionChanged);
+ }
}
}
diff --git a/src/com/android/contacts/list/MultiplePhonePickerItemView.java b/src/com/android/contacts/list/MultiplePhonePickerItemView.java
index af4c6c8..4801d33 100644
--- a/src/com/android/contacts/list/MultiplePhonePickerItemView.java
+++ b/src/com/android/contacts/list/MultiplePhonePickerItemView.java
@@ -38,8 +38,6 @@
private int mChipRightMargin;
private int mCheckBoxMargin;
- private OnClickListener mCheckBoxClickListener;
-
public long phoneId;
// phoneNumber only validates when phoneId = INVALID_PHONE_ID
public String phoneNumber;
@@ -55,10 +53,6 @@
resources.getDimensionPixelOffset(R.dimen.list_item_header_checkbox_margin);
}
- public void setOnCheckBoxClickListener(OnClickListener checkBoxClickListener) {
- mCheckBoxClickListener = checkBoxClickListener;
- }
-
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isVisible(mChipView)) {
@@ -118,7 +112,8 @@
public CheckBox getCheckBoxView() {
if (mCheckBox == null) {
mCheckBox = new CheckBox(mContext);
- mCheckBox.setOnClickListener(mCheckBoxClickListener);
+ mCheckBox.setClickable(false);
+ mCheckBox.setFocusable(false);
addView(mCheckBox);
}
return mCheckBox;
diff --git a/src/com/android/contacts/list/MultiplePhoneSelection.java b/src/com/android/contacts/list/MultiplePhoneSelection.java
deleted file mode 100644
index e9249e4..0000000
--- a/src/com/android/contacts/list/MultiplePhoneSelection.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * 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 com.android.contacts.MultiplePhonePickerActivity;
-
-import android.content.ContentUris;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.ContactsContract.Intents;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.text.TextUtils;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * This class is used to keep the user's selection in MODE_PICK_MULTIPLE_PHONES mode.
- */
-public class MultiplePhoneSelection {
-
- private final MultiplePhonePickerActivity mMultiplePhoneSelectionActivity;
-
- private static final String TEL_SCHEME = "tel";
-
- public static final String EXTRA_SELECTION =
- "com.android.contacts.MultiplePhoneSelectionActivity.UserSelection.extra.SELECTION";
- private static final String SELECTED_UNKNOWN_PHONES_KEY = "selected_unknown_phones";
- private static final String SELECTED_PHONE_IDS_KEY = "selected_phone_id";
-
- /** The PHONE_ID of selected number in user contacts*/
- private HashSet<Long> mSelectedPhoneIds = new HashSet<Long>();
-
- /** The selected phone numbers in the PhoneNumberAdapter */
- private HashSet<String> mSelectedPhoneNumbers = new HashSet<String>();
-
- public MultiplePhoneSelection(MultiplePhonePickerActivity multiplePhonePickerActivity) {
- this.mMultiplePhoneSelectionActivity = multiplePhonePickerActivity;
- }
-
- public void saveInstanceState(Bundle icicle) {
- int selectedUnknownsCount = mSelectedPhoneNumbers.size();
- if (selectedUnknownsCount > 0) {
- String[] selectedUnknows = new String[selectedUnknownsCount];
- icicle.putStringArray(SELECTED_UNKNOWN_PHONES_KEY,
- mSelectedPhoneNumbers.toArray(selectedUnknows));
- }
- int selectedKnownsCount = mSelectedPhoneIds.size();
- if (selectedKnownsCount > 0) {
- long[] selectedPhoneIds = new long [selectedKnownsCount];
- int index = 0;
- for (Long phoneId : mSelectedPhoneIds) {
- selectedPhoneIds[index++] = phoneId.longValue();
- }
- icicle.putLongArray(SELECTED_PHONE_IDS_KEY, selectedPhoneIds);
-
- }
- }
-
- public void restoreInstanceState(Bundle icicle) {
- if (icicle != null) {
- setSelection(icicle.getStringArray(SELECTED_UNKNOWN_PHONES_KEY),
- icicle.getLongArray(SELECTED_PHONE_IDS_KEY));
- }
- }
-
- public void setSelection(final String[] selecedUnknownNumbers, final long[] selectedPhoneIds) {
- if (selecedUnknownNumbers != null) {
- for (String number : selecedUnknownNumbers) {
- setPhoneSelected(number, true);
- }
- }
- if (selectedPhoneIds != null) {
- for (long id : selectedPhoneIds) {
- setPhoneSelected(id, true);
- }
- }
- }
-
- public void setSelection(final List<String> selecedUnknownNumbers,
- final List<Long> selectedPhoneIds) {
- if (selecedUnknownNumbers != null) {
- setPhoneNumbersSelected(selecedUnknownNumbers, true);
- }
- if (selectedPhoneIds != null) {
- setPhoneIdsSelected(selectedPhoneIds, true);
- }
- }
-
- private void setPhoneNumbersSelected(final List<String> phoneNumbers, boolean selected) {
- if (selected) {
- mSelectedPhoneNumbers.addAll(phoneNumbers);
- } else {
- mSelectedPhoneNumbers.removeAll(phoneNumbers);
- }
- }
-
- private void setPhoneIdsSelected(final List<Long> phoneIds, boolean selected) {
- if (selected) {
- mSelectedPhoneIds.addAll(phoneIds);
- } else {
- mSelectedPhoneIds.removeAll(phoneIds);
- }
- }
-
- public void setPhoneSelected(final String phoneNumber, boolean selected) {
- if (!TextUtils.isEmpty(phoneNumber)) {
- if (selected) {
- mSelectedPhoneNumbers.add(phoneNumber);
- } else {
- mSelectedPhoneNumbers.remove(phoneNumber);
- }
- }
- }
-
- public void setPhoneSelected(long phoneId, boolean selected) {
- if (selected) {
- mSelectedPhoneIds.add(phoneId);
- } else {
- mSelectedPhoneIds.remove(phoneId);
- }
- }
-
- public boolean isSelected(long phoneId) {
- return mSelectedPhoneIds.contains(phoneId);
- }
-
- public boolean isSelected(final String phoneNumber) {
- return mSelectedPhoneNumbers.contains(phoneNumber);
- }
-
- public void setAllPhonesSelected(boolean selected) {
- if (selected) {
- Cursor cursor = this.mMultiplePhoneSelectionActivity.mAdapter.getCursor();
- if (cursor != null) {
- int backupPos = cursor.getPosition();
- cursor.moveToPosition(-1);
- while (cursor.moveToNext()) {
- setPhoneSelected(cursor
- .getLong(MultiplePhonePickerActivity.PHONE_ID_COLUMN_INDEX), true);
- }
- cursor.moveToPosition(backupPos);
- }
- for (String number : this.mMultiplePhoneSelectionActivity.mPhoneNumberAdapter
- .getFilteredPhoneNumbers()) {
- setPhoneSelected(number, true);
- }
- } else {
- mSelectedPhoneIds.clear();
- mSelectedPhoneNumbers.clear();
- }
- }
-
- public boolean isAllSelected() {
- return selectedCount() == this.mMultiplePhoneSelectionActivity.mPhoneNumberAdapter
- .getFilteredPhoneNumbers().size()
- + this.mMultiplePhoneSelectionActivity.mAdapter.getCount();
- }
-
- public int selectedCount() {
- return mSelectedPhoneNumbers.size() + mSelectedPhoneIds.size();
- }
-
- public Iterator<Long> getSelectedPhonIds() {
- return mSelectedPhoneIds.iterator();
- }
-
- private int fillSelectedNumbers(Uri[] uris, int from) {
- int count = mSelectedPhoneNumbers.size();
- if (count == 0)
- return from;
- // Below loop keeps phone numbers by initial order.
- List<String> phoneNumbers = this.mMultiplePhoneSelectionActivity.mPhoneNumberAdapter
- .getPhoneNumbers();
- for (String phoneNumber : phoneNumbers) {
- if (isSelected(phoneNumber)) {
- Uri.Builder ub = new Uri.Builder();
- ub.scheme(TEL_SCHEME);
- ub.encodedOpaquePart(phoneNumber);
- uris[from++] = ub.build();
- }
- }
- return from;
- }
-
- private int fillSelectedPhoneIds(Uri[] uris, int from) {
- int count = mSelectedPhoneIds.size();
- if (count == 0)
- return from;
- Iterator<Long> it = mSelectedPhoneIds.iterator();
- while (it.hasNext()) {
- uris[from++] = ContentUris.withAppendedId(Phone.CONTENT_URI, it.next());
- }
- return from;
- }
-
- private Uri[] getSelected() {
- Uri[] uris = new Uri[mSelectedPhoneNumbers.size() + mSelectedPhoneIds.size()];
- int from = fillSelectedNumbers(uris, 0);
- fillSelectedPhoneIds(uris, from);
- return uris;
- }
-
- public Intent createSelectionIntent() {
- Intent intent = new Intent();
- intent.putExtra(Intents.EXTRA_PHONE_URIS, getSelected());
-
- return intent;
- }
-
- public void fillSelectionForSearchMode(Bundle bundle) {
- bundle.putParcelableArray(EXTRA_SELECTION, getSelected());
- }
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/list/OnMultiplePhoneNumberPickerActionListener.java b/src/com/android/contacts/list/OnMultiplePhoneNumberPickerActionListener.java
new file mode 100644
index 0000000..ac010ba
--- /dev/null
+++ b/src/com/android/contacts/list/OnMultiplePhoneNumberPickerActionListener.java
@@ -0,0 +1,34 @@
+/*
+ * 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.net.Uri;
+
+/**
+ * Action callbacks that can be sent by a multiple phone number picker.
+ */
+public interface OnMultiplePhoneNumberPickerActionListener {
+
+ /**
+ * Returns the selected phone numbers to the requester.
+ */
+ void onPhoneNumbersSelectedAction(Uri[] dataUris);
+
+ /**
+ * Closes the picker without changing the selection.
+ */
+ void onFinishAction();
+}
diff --git a/src/com/android/contacts/list/PhoneNumberListAdapter.java b/src/com/android/contacts/list/PhoneNumberListAdapter.java
index 70ec4ec..ffac30b 100644
--- a/src/com/android/contacts/list/PhoneNumberListAdapter.java
+++ b/src/com/android/contacts/list/PhoneNumberListAdapter.java
@@ -64,6 +64,10 @@
mUnknownNameText = context.getText(android.R.string.unknownName);
}
+ protected CharSequence getUnknownNameText() {
+ return mUnknownNameText;
+ }
+
@Override
public void configureLoader(CursorLoader loader) {
loader.setUri(buildSectionIndexerUri(Phone.CONTENT_URI));