diff options
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/app/SearchDialog.java | 11 | ||||
-rw-r--r-- | core/java/android/app/SearchManager.java | 66 | ||||
-rw-r--r-- | core/java/android/app/SuggestionsAdapter.java | 124 |
3 files changed, 125 insertions, 76 deletions
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index bcb2791..0bb483b 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -1202,16 +1202,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS protected boolean launchSuggestion(int position, int actionKey, String actionMsg) { Cursor c = mSuggestionsAdapter.getCursor(); if ((c != null) && c.moveToPosition(position)) { - // let the cursor know which position was clicked - final Bundle clickResponse = new Bundle(1); - clickResponse.putInt(SearchManager.RESPOND_EXTRA_POSITION_CLICKED, position); - final Bundle response = c.respond(clickResponse); - - // the convention is to send a position to select in response to a click (if applicable) - final int posToSelect = response.getInt( - SearchManager.RESPOND_EXTRA_POSITION_SELECTED, - SuggestionsAdapter.NO_ITEM_TO_SELECT); - mSuggestionsAdapter.setListItemToSelect(posToSelect); + mSuggestionsAdapter.callCursorOnClick(c, position); // launch the intent Intent intent = createIntentFromSuggestion(c, actionKey, actionMsg); diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java index 841e6aa..b0c248c 100644 --- a/core/java/android/app/SearchManager.java +++ b/core/java/android/app/SearchManager.java @@ -1167,38 +1167,50 @@ public class SearchManager */ public final static String EXTRA_DATA_KEY = "intent_extra_data_key"; - /** - * Used by the search dialog to ask the global search provider whether there are any pending - * sources that have yet to respond. Specifically, the search dialog will call - * {@link Cursor#respond} with a bundle containing this extra as a key, and expect the same key - * to be in the response, with a boolean value indicating whether there are pending sources. + * Defines the constants used in the communication between {@link android.app.SearchDialog} and + * the global search provider via {@link Cursor#respond(android.os.Bundle)}. * - * {@hide} + * @hide */ - public final static String RESPOND_EXTRA_PENDING_SOURCES = "respond_extra_pending_sources"; + public static class DialogCursorProtocol { - /** - * Used by the search dialog to tell the cursor that supplied suggestions which item was clicked - * before launching the intent. The search dialog will call {@link Cursor#respond} with a - * bundle containing this extra as a key and the position that was clicked as the value. - * - * The response bundle will use {@link #RESPOND_EXTRA_POSITION_SELECTED} to return an int value - * of the index that should be selected, if applicable. - * - * {@hide} - */ - public final static String RESPOND_EXTRA_POSITION_CLICKED = "respond_extra_position_clicked"; + /** + * The sent bundle will contain this integer key, with a value set to one of the events + * below. + */ + public final static String METHOD = "DialogCursorProtocol.method"; - /** - * Used as a key in the response bundle from a call to {@link Cursor#respond} that sends the - * position that is clicked. - * - * @see #RESPOND_EXTRA_POSITION_CLICKED - * - * {@hide} - */ - public final static String RESPOND_EXTRA_POSITION_SELECTED = "respond_extra_position_selected"; + /** + * After data has been refreshed. + */ + public final static int POST_REFRESH = 0; + public final static String POST_REFRESH_RECEIVE_ISPENDING + = "DialogCursorProtocol.POST_REFRESH.isPending"; + public final static String POST_REFRESH_RECEIVE_DISPLAY_NOTIFY + = "DialogCursorProtocol.POST_REFRESH.displayNotify"; + + /** + * Just before closing the cursor. + */ + public final static int PRE_CLOSE = 1; + public final static String PRE_CLOSE_SEND_MAX_DISPLAY_POS + = "DialogCursorProtocol.PRE_CLOSE.sendDisplayPosition"; + + /** + * When a position has been clicked. + */ + public final static int CLICK = 2; + public final static String CLICK_SEND_POSITION + = "DialogCursorProtocol.CLICK.sendPosition"; + public final static String CLICK_RECEIVE_SELECTED_POS + = "DialogCursorProtocol.CLICK.receiveSelectedPosition"; + + /** + * When the threshold received in {@link #POST_REFRESH_RECEIVE_DISPLAY_NOTIFY} is displayed. + */ + public final static int THRESH_HIT = 3; + } /** * Intent extra data key: Use this key with Intent.ACTION_SEARCH and diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java index 9c82429..48d8d12 100644 --- a/core/java/android/app/SuggestionsAdapter.java +++ b/core/java/android/app/SuggestionsAdapter.java @@ -33,6 +33,8 @@ import android.widget.ImageView; import android.widget.ResourceCursorAdapter; import android.widget.TextView; +import static android.app.SearchManager.DialogCursorProtocol; + import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -44,15 +46,7 @@ import java.util.WeakHashMap; * @hide */ class SuggestionsAdapter extends ResourceCursorAdapter { - // The value used to query a cursor whether it is still expecting more input, - // so we can correctly display (or not display) the 'working' spinner in the search dialog. - public static final String IS_WORKING = "isWorking"; - - // The value used to tell a cursor to display the corpus selectors, if this is global - // search. Also returns the index of the more results item to allow the SearchDialog - // to tell the ListView to scroll to that list item. - public static final String SHOW_CORPUS_SELECTORS = "showCorpusSelectors"; - + private static final boolean DBG = false; private static final String LOG_TAG = "SuggestionsAdapter"; @@ -73,10 +67,16 @@ class SuggestionsAdapter extends ResourceCursorAdapter { // a particular list item should be selected upon the next call to notifyDataSetChanged. // This is used to indicate the index of the "More results..." list item so that when // the data set changes after a click of "More results...", we can correctly tell the - // ListView to scroll to the right line item. It gets reset to NO_ITEM_TO_SELECT every time it + // ListView to scroll to the right line item. It gets reset to NONE every time it // is consumed. - private int mListItemToSelect = NO_ITEM_TO_SELECT; - static final int NO_ITEM_TO_SELECT = -1; + private int mListItemToSelect = NONE; + static final int NONE = -1; + + // holds the maximum position that has been displayed to the user + int mMaxDisplayed = NONE; + + // holds the position that, when displayed, should result in notifying the cursor + int mDisplayNotifyPos = NONE; public SuggestionsAdapter(Context context, SearchDialog searchDialog, SearchableInfo searchable, WeakHashMap<String, Drawable> outsideDrawablesCache, boolean globalSearchMode) { @@ -127,6 +127,11 @@ class SuggestionsAdapter extends ResourceCursorAdapter { @Override public void changeCursor(Cursor c) { if (DBG) Log.d(LOG_TAG, "changeCursor(" + c + ")"); + + if (mCursor != null) { + callCursorPreClose(mCursor); + } + super.changeCursor(c); if (c != null) { mFormatCol = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_FORMAT); @@ -135,39 +140,69 @@ class SuggestionsAdapter extends ResourceCursorAdapter { mIconName1Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1); mIconName2Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_2); } - updateWorking(); } - + + /** + * Handle sending and receiving information associated with + * {@link DialogCursorProtocol#PRE_CLOSE}. + * + * @param cursor The cursor to call. + */ + private void callCursorPreClose(Cursor cursor) { + final Bundle request = new Bundle(); + request.putInt(DialogCursorProtocol.METHOD, DialogCursorProtocol.PRE_CLOSE); + request.putInt(DialogCursorProtocol.PRE_CLOSE_SEND_MAX_DISPLAY_POS, mMaxDisplayed); + final Bundle response = cursor.respond(request); + + mMaxDisplayed = -1; + } + @Override public void notifyDataSetChanged() { + if (DBG) Log.d(LOG_TAG, "notifyDataSetChanged"); super.notifyDataSetChanged(); - updateWorking(); - if (mListItemToSelect != NO_ITEM_TO_SELECT) { + + callCursorPostRefresh(mCursor); + + // look out for the pending item we are supposed to scroll to + if (mListItemToSelect != NONE) { mSearchDialog.setListSelection(mListItemToSelect); - mListItemToSelect = NO_ITEM_TO_SELECT; + mListItemToSelect = NONE; } } - + /** - * Specifies the list item to select upon next call of {@link #notifyDataSetChanged()}, - * in order to let us scroll the "More results..." list item to the top of the screen - * (or as close as it can get) when clicked. + * Handle sending and receiving information associated with + * {@link DialogCursorProtocol#POST_REFRESH}. + * + * @param cursor The cursor to call. */ - public void setListItemToSelect(int index) { - mListItemToSelect = index; + private void callCursorPostRefresh(Cursor cursor) { + final Bundle request = new Bundle(); + request.putInt(DialogCursorProtocol.METHOD, DialogCursorProtocol.POST_REFRESH); + final Bundle response = cursor.respond(request); + + mSearchDialog.setWorking( + response.getBoolean(DialogCursorProtocol.POST_REFRESH_RECEIVE_ISPENDING, false)); + + mDisplayNotifyPos = + response.getInt(DialogCursorProtocol.POST_REFRESH_RECEIVE_DISPLAY_NOTIFY, -1); } - + /** - * Updates the search dialog according to the current working status of the cursor. + * Tell the cursor which position was clicked, handling sending and receiving information + * associated with {@link DialogCursorProtocol#CLICK}. + * + * @param cursor The cursor + * @param position The position that was clicked. */ - private void updateWorking() { - if (!mGlobalSearchMode || mCursor == null) return; - - Bundle request = new Bundle(); - request.putString(SearchManager.RESPOND_EXTRA_PENDING_SOURCES, "DUMMY"); - Bundle response = mCursor.respond(request); - - mSearchDialog.setWorking(response.getBoolean(SearchManager.RESPOND_EXTRA_PENDING_SOURCES)); + void callCursorOnClick(Cursor cursor, int position) { + final Bundle request = new Bundle(1); + request.putInt(DialogCursorProtocol.METHOD, DialogCursorProtocol.CLICK); + request.putInt(DialogCursorProtocol.CLICK_SEND_POSITION, position); + final Bundle response = cursor.respond(request); + mListItemToSelect = response.getInt( + DialogCursorProtocol.CLICK_RECEIVE_SELECTED_POS, SuggestionsAdapter.NONE); } /** @@ -179,7 +214,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter { v.setTag(new ChildViewCache(v)); return v; } - + /** * Cache of the child views of drop-drown list items, to avoid looking up the children * each time the contents of a list item are changed. @@ -201,11 +236,22 @@ class SuggestionsAdapter extends ResourceCursorAdapter { @Override public void bindView(View view, Context context, Cursor cursor) { ChildViewCache views = (ChildViewCache) view.getTag(); - boolean isHtml = false; - if (mFormatCol >= 0) { - String format = cursor.getString(mFormatCol); - isHtml = "html".equals(format); + final int pos = cursor.getPosition(); + + // update the maximum position displayed since last refresh + if (pos > mMaxDisplayed) { + mMaxDisplayed = pos; + } + + // if the cursor wishes to be notified about this position, send it + if (mDisplayNotifyPos != NONE && pos == mDisplayNotifyPos) { + final Bundle request = new Bundle(); + request.putInt(DialogCursorProtocol.METHOD, DialogCursorProtocol.THRESH_HIT); + mCursor.respond(request); + mDisplayNotifyPos = NONE; // only notify the first time } + + final boolean isHtml = mFormatCol > 0 && "html".equals(cursor.getString(mFormatCol)); setViewText(cursor, views.mText1, mText1Col, isHtml); setViewText(cursor, views.mText2, mText2Col, isHtml); setViewIcon(cursor, views.mIcon1, mIconName1Col); @@ -400,7 +446,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter { */ public static String getColumnString(Cursor cursor, String columnName) { int col = cursor.getColumnIndex(columnName); - if (col == NO_ITEM_TO_SELECT) { + if (col == NONE) { return null; } return cursor.getString(col); |