Moving search UI from ContactsListActivity to the Fragment
Change-Id: I98f811fb178f060376c04fe2bc4037ec9f8e193a
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index 9681ef0..1eaa6b6 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -123,7 +123,7 @@
*/
@SuppressWarnings("deprecation")
public class ContactsListActivity extends Activity implements View.OnCreateContextMenuListener,
- View.OnClickListener, View.OnKeyListener, TextWatcher, TextView.OnEditorActionListener,
+ View.OnClickListener, View.OnKeyListener,
OnFocusChangeListener, OnTouchListener, ContactsApplicationController {
private static final String TAG = "ContactsListActivity";
@@ -435,7 +435,6 @@
private ContactsPreferences mContactsPrefs;
public int mDisplayOrder;
private int mSortOrder;
- private SearchEditText mSearchEditText;
private ContentObserver mProviderStatusObserver = new ContentObserver(new Handler()) {
@@ -587,6 +586,10 @@
public void onDeleteContactAction(Uri contactUri) {
doContactDelete(contactUri);
}
+
+ public void onFinishAction() {
+ onBackPressed();
+ }
});
fragment.setContextMenuAdapter(new ContactBrowseListContextMenuAdapter(fragment));
mListFragment = fragment;
@@ -617,6 +620,8 @@
setResult(RESULT_OK, intent.setData(contactUri));
finish();
}
+
+ // TODO: finish action to support search in the picker
});
mListFragment = fragment;
@@ -705,16 +710,6 @@
getContentResolver().unregisterContentObserver(mProviderStatusObserver);
}
-
- /**
- * Configures search UI.
- */
- private void setupSearchView() {
- mSearchEditText = (SearchEditText)findViewById(R.id.search_src_text);
- mSearchEditText.addTextChangedListener(this);
- mSearchEditText.setOnEditorActionListener(this);
- mSearchEditText.setText(mInitialFilter);
- }
public int getSummaryDisplayNameColumnIndex() {
if (mDisplayOrder == ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY) {
return SUMMARY_DISPLAY_NAME_PRIMARY_COLUMN_INDEX;
@@ -765,10 +760,6 @@
// TODO move this to onAttach of the corresponding fragment
mListView = (ListView) findViewById(android.R.id.list);
- if (mSearchMode) {
- setupSearchView();
- }
-
View emptyView = mListView.getEmptyView();
if (emptyView instanceof ContactListEmptyView) {
mEmptyView = (ContactListEmptyView)emptyView;
@@ -786,11 +777,6 @@
setDefaultMode();
}
- // See if we were invoked with a filter
- if (mSearchMode) {
- mSearchEditText.requestFocus();
- }
-
if (!mSearchMode && !checkProviderState(mJustCreated)) {
return;
}
@@ -900,13 +886,6 @@
retryUpgrade.setOnClickListener(listener);
}
- public String getTextFilter() {
- if (mSearchEditText != null) {
- return mSearchEditText.getText().toString();
- }
- return null;
- }
-
@Override
protected void onRestart() {
super.onRestart();
@@ -918,7 +897,7 @@
// The cursor was killed off in onStop(), so we need to get a new one here
// We do not perform the query if a filter is set on the list because the
// filter will cause the query to happen anyway
- if (TextUtils.isEmpty(getTextFilter())) {
+ if (TextUtils.isEmpty(mListFragment.getQueryString())) {
startQuery();
} else {
// Run the filtered query on the adapter
@@ -1036,15 +1015,13 @@
* search text edit.
*/
protected void onSearchTextChanged() {
- Filter filter = mAdapter.getFilter();
- filter.filter(getTextFilter());
}
/**
* Starts a new activity that will run a search query and display search results.
*/
protected void doSearch() {
- String query = getTextFilter();
+ String query = mListFragment.getQueryString();
if (TextUtils.isEmpty(query)) {
return;
}
@@ -1321,33 +1298,6 @@
return false;
}
- /**
- * Event handler for search UI.
- */
- public void afterTextChanged(Editable s) {
- onSearchTextChanged();
- }
-
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- }
-
- /**
- * Event handler for search UI.
- */
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if (actionId == EditorInfo.IME_ACTION_DONE) {
- hideSoftKeyboard();
- if (TextUtils.isEmpty(getTextFilter())) {
- finish();
- }
- return true;
- }
- return false;
- }
-
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
@@ -1447,18 +1397,6 @@
return false;
}
- /**
- * Dismisses the search UI along with the keyboard if the filter text is empty.
- */
- public boolean onKeyPreIme(int keyCode, KeyEvent event) {
- if (mSearchMode && keyCode == KeyEvent.KEYCODE_BACK && TextUtils.isEmpty(getTextFilter())) {
- hideSoftKeyboard();
- onBackPressed();
- return true;
- }
- return false;
- }
-
public void onListItemClick(int position, long id) {
if (mSearchMode &&
((ContactItemListAdapter)(mAdapter)).isSearchAllContactsItemPosition(position)) {
@@ -2054,7 +1992,7 @@
}
String[] projection = getProjectionForQuery();
- if (mSearchMode && TextUtils.isEmpty(getTextFilter())) {
+ if (mSearchMode && TextUtils.isEmpty(mListFragment.getQueryString())) {
mAdapter.changeCursor(new MatrixCursor(projection));
return;
}
@@ -2152,7 +2090,7 @@
*/
public Cursor doFilter(String filter) {
String[] projection = getProjectionForQuery();
- if (mSearchMode && TextUtils.isEmpty(getTextFilter())) {
+ if (mSearchMode && TextUtils.isEmpty(mListFragment.getQueryString())) {
return new MatrixCursor(projection);
}
diff --git a/src/com/android/contacts/JoinContactActivity.java b/src/com/android/contacts/JoinContactActivity.java
index bacd0af..21f5929 100644
--- a/src/com/android/contacts/JoinContactActivity.java
+++ b/src/com/android/contacts/JoinContactActivity.java
@@ -191,7 +191,7 @@
if (mAdapter.getSuggestionsCursorCount() == 0
|| !mAdapter.isJoinModeShowAllContacts()) {
- startQuery(getContactFilterUri(getTextFilter()),
+ startQuery(getContactFilterUri(mListFragment.getQueryString()),
CONTACTS_SUMMARY_PROJECTION,
Contacts._ID + " != " + mTargetContactId
+ " AND " + ContactsContract.Contacts.IN_VISIBLE_GROUP + "=1", null,
diff --git a/src/com/android/contacts/MultiplePhonePickerActivity.java b/src/com/android/contacts/MultiplePhonePickerActivity.java
index 492f419..1d1fbbb 100644
--- a/src/com/android/contacts/MultiplePhonePickerActivity.java
+++ b/src/com/android/contacts/MultiplePhonePickerActivity.java
@@ -296,7 +296,7 @@
@Override
public Cursor doFilter(String filter) {
String[] projection = getProjectionForQuery();
- if (mSearchMode && TextUtils.isEmpty(getTextFilter())) {
+ if (mSearchMode && TextUtils.isEmpty(mListFragment.getQueryString())) {
return new MatrixCursor(projection);
}
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index e280779..0fc025e 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -123,4 +123,10 @@
public void smsContact(Uri contactUri) {
mListener.onSmsContactAction(contactUri);
}
+
+ @Override
+ protected void finish() {
+ super.finish();
+ mListener.onFinishAction();
+ }
}
diff --git a/src/com/android/contacts/list/ContactEntryListAdapter.java b/src/com/android/contacts/list/ContactEntryListAdapter.java
index fc6d1a9..e5b9087 100644
--- a/src/com/android/contacts/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/list/ContactEntryListAdapter.java
@@ -50,10 +50,17 @@
private boolean mNameHighlightingEnabled;
private ContactPhotoLoader mPhotoLoader;
+ // TODO move to Loader
+ protected String mQueryString;
+
public ContactEntryListAdapter(Context context) {
super(context);
}
+ public void setQueryString(String queryString) {
+ mQueryString = queryString;
+ }
+
public Context getContext() {
return mContext;
}
diff --git a/src/com/android/contacts/list/ContactEntryListFragment.java b/src/com/android/contacts/list/ContactEntryListFragment.java
index cc7a1f7..0bf7735 100644
--- a/src/com/android/contacts/list/ContactEntryListFragment.java
+++ b/src/com/android/contacts/list/ContactEntryListFragment.java
@@ -22,25 +22,35 @@
import com.android.contacts.R;
import com.android.contacts.widget.ContextMenuAdapter;
import com.android.contacts.widget.PinnedHeaderListView;
+import com.android.contacts.widget.SearchEditText;
+import com.android.contacts.widget.SearchEditText.OnCloseListener;
import android.app.Fragment;
import android.content.Context;
+import android.text.Editable;
import android.text.Html;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.AdapterView;
+import android.widget.Filter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AbsListView.OnScrollListener;
+import android.widget.AdapterView.OnItemClickListener;
/**
* Common base class for various contact-related list fragments.
*/
-public abstract class ContactEntryListFragment extends Fragment
- implements AdapterView.OnItemClickListener, OnScrollListener {
+public abstract class ContactEntryListFragment extends Fragment implements
+ OnItemClickListener, OnScrollListener, TextWatcher,
+ TextView.OnEditorActionListener, OnCloseListener {
private boolean mSectionHeaderDisplayEnabled;
private boolean mPhotoLoaderEnabled;
@@ -56,6 +66,7 @@
private int mDisplayOrder;
private ContextMenuAdapter mContextMenuAdapter;
private ContactPhotoLoader mPhotoLoader;
+ private SearchEditText mSearchEditText;
protected abstract View inflateView(LayoutInflater inflater, ViewGroup container);
protected abstract ContactEntryListAdapter createListAdapter();
@@ -65,6 +76,12 @@
return mAdapter;
}
+ /**
+ * Override to provide logic that dismisses this fragment.
+ */
+ protected void finish() {
+ }
+
public void setSectionHeaderDisplayEnabled(boolean flag) {
mSectionHeaderDisplayEnabled = flag;
}
@@ -120,7 +137,6 @@
}
}
-
@Deprecated
public void setContactsApplicationController(ContactsApplicationController controller) {
mAppController = controller;
@@ -179,6 +195,22 @@
configurePinnedHeader();
+ if (isPhotoLoaderEnabled()) {
+ mPhotoLoader =
+ new ContactPhotoLoader(getActivity(), R.drawable.ic_contact_list_picture);
+ mAdapter.setPhotoLoader(mPhotoLoader);
+ mListView.setOnScrollListener(this);
+ }
+
+ if (isSearchMode()) {
+ mSearchEditText = (SearchEditText)view.findViewById(R.id.search_src_text);
+ mSearchEditText.setText(getQueryString());
+ mSearchEditText.addTextChangedListener(this);
+ mSearchEditText.setOnEditorActionListener(this);
+ mSearchEditText.setOnCloseListener(this);
+ mAdapter.setQueryString(getQueryString());
+ }
+
if (isSearchResultsMode()) {
TextView titleText = (TextView)view.findViewById(R.id.search_results_for);
if (titleText != null) {
@@ -186,13 +218,6 @@
"<b>" + getQueryString() + "</b>")));
}
}
-
- if (isPhotoLoaderEnabled()) {
- mPhotoLoader =
- new ContactPhotoLoader(getActivity(), R.drawable.ic_contact_list_picture);
- mAdapter.setPhotoLoader(mPhotoLoader);
- mListView.setOnScrollListener(this);
- }
}
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
@@ -213,6 +238,9 @@
if (isPhotoLoaderEnabled()) {
mPhotoLoader.resume();
}
+ if (isSearchMode()) {
+ mSearchEditText.requestFocus();
+ }
}
@Override
@@ -239,11 +267,49 @@
onItemClick(position, id);
}
-
private void hideSoftKeyboard() {
// Hide soft keyboard, if visible
InputMethodManager inputMethodManager = (InputMethodManager)
getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(mListView.getWindowToken(), 0);
}
+
+ /**
+ * Event handler for search UI.
+ */
+ public void afterTextChanged(Editable s) {
+ String query = s.toString().trim();
+ setQueryString(query);
+ mAdapter.setQueryString(query);
+ Filter filter = mAdapter.getFilter();
+ filter.filter(query);
+ }
+
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ /**
+ * Event handler for search UI.
+ */
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ hideSoftKeyboard();
+ if (TextUtils.isEmpty(getQueryString())) {
+ finish();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Dismisses the search UI along with the keyboard if the filter text is empty.
+ */
+ public void onClose() {
+ hideSoftKeyboard();
+ finish();
+ }
}
diff --git a/src/com/android/contacts/list/ContactItemListAdapter.java b/src/com/android/contacts/list/ContactItemListAdapter.java
index a1d1f12..bd0efa3 100644
--- a/src/com/android/contacts/list/ContactItemListAdapter.java
+++ b/src/com/android/contacts/list/ContactItemListAdapter.java
@@ -101,7 +101,7 @@
*/
@Override
public void onContentChanged() {
- CharSequence constraint = contactsListActivity.getTextFilter();
+ CharSequence constraint = mQueryString;
if (!TextUtils.isEmpty(constraint)) {
// Reset the filter state then start an async filter operation
Filter filter = getFilter();
@@ -123,7 +123,7 @@
}
if (contactsListActivity.mSearchMode) {
- return TextUtils.isEmpty(contactsListActivity.getTextFilter());
+ return TextUtils.isEmpty(mQueryString);
} else if ((contactsListActivity.mMode & ContactsListActivity.MODE_MASK_CREATE_NEW) ==
ContactsListActivity.MODE_MASK_CREATE_NEW) {
// This mode mask adds a header and we always want it to show up, even
@@ -219,7 +219,7 @@
int count = getRealCount();
if (contactsListActivity.mSearchMode
- && !TextUtils.isEmpty(contactsListActivity.getTextFilter())) {
+ && !TextUtils.isEmpty(mQueryString)) {
text = contactsListActivity.getQuantityText(count, R.string.listFoundAllContactsZero,
R.plurals.searchFoundContacts);
} else {
diff --git a/src/com/android/contacts/list/OnContactBrowserActionListener.java b/src/com/android/contacts/list/OnContactBrowserActionListener.java
index b038108..56f9bbc 100644
--- a/src/com/android/contacts/list/OnContactBrowserActionListener.java
+++ b/src/com/android/contacts/list/OnContactBrowserActionListener.java
@@ -67,4 +67,8 @@
*/
void onSmsContactAction(Uri contactUri);
+ /**
+ * Closes the contact browser.
+ */
+ void onFinishAction();
}
diff --git a/src/com/android/contacts/SearchEditText.java b/src/com/android/contacts/widget/SearchEditText.java
similarity index 80%
rename from src/com/android/contacts/SearchEditText.java
rename to src/com/android/contacts/widget/SearchEditText.java
index 7683f23..1a50976 100644
--- a/src/com/android/contacts/SearchEditText.java
+++ b/src/com/android/contacts/widget/SearchEditText.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.contacts;
+package com.android.contacts.widget;
import android.content.Context;
import android.graphics.drawable.Drawable;
@@ -31,12 +31,21 @@
private boolean mMagnifyingGlassShown = true;
private Drawable mMagnifyingGlass;
+ private OnCloseListener mListener;
+
+ public interface OnCloseListener {
+ void onClose();
+ }
public SearchEditText(Context context, AttributeSet attrs) {
super(context, attrs);
mMagnifyingGlass = getCompoundDrawables()[2];
}
+ public void setOnCloseListener(OnCloseListener listener) {
+ this.mListener = listener;
+ }
+
/**
* Conditionally shows a magnifying glass icon on the right side of the text field
* when the text it empty.
@@ -57,13 +66,14 @@
}
/**
- * Forwards the onKeyPreIme call to the view's activity.
+ * Dismisses the search UI along with the keyboard if the filter text is empty.
*/
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
- if (((ContactsListActivity)getContext()).onKeyPreIme(keyCode, event)) {
+ if (keyCode == KeyEvent.KEYCODE_BACK && TextUtils.isEmpty(getText()) && mListener != null) {
+ mListener.onClose();
return true;
}
- return super.onKeyPreIme(keyCode, event);
+ return false;
}
}