From 077357ccf0c8b35094a69c3fc8bddd9ee605cf78 Mon Sep 17 00:00:00 2001 From: Bjorn Bringert Date: Wed, 23 Sep 2009 13:57:24 +0100 Subject: [PATCH] Back button in search always goes back or closes search Before, the back button had different behavior depending on which part of the search dialog had focus, and depending on whether there were more suggestions than could fit in the visible space in the drop-down. This change makes the behavior of the BACK button more predictable, by always going back to QSB when pivoted into a source, and closing the search dialog when in QSB. Fixes http://b/issue?id=2126526 "One tap of back button when entering text to search should always take you back to previous page" Change-Id: I7b3553122eaa1a5d87ac966d5ab2a9f432063cc9 --- core/java/android/app/SearchDialog.java | 99 ++++++++++++------------- core/res/res/layout/search_bar.xml | 5 +- 2 files changed, 51 insertions(+), 53 deletions(-) diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index a2c95f420f8f6..6d55f06dc6ebf 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -30,7 +30,6 @@ import android.content.pm.ResolveInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.database.Cursor; -import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; @@ -64,9 +63,9 @@ import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; -import android.widget.ListAdapter; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemSelectedListener; @@ -182,6 +181,9 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS theWindow.setAttributes(lp); // get the view elements for local access + SearchBar searchBar = (SearchBar) findViewById(com.android.internal.R.id.search_bar); + searchBar.setSearchDialog(this); + mBadgeLabel = (TextView) findViewById(com.android.internal.R.id.search_badge); mSearchAutoComplete = (SearchAutoComplete) findViewById(com.android.internal.R.id.search_src_text); @@ -205,8 +207,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS mVoiceButton.setOnClickListener(mVoiceButtonClickListener); mVoiceButton.setOnKeyListener(mButtonsKeyListener); - mSearchAutoComplete.setSearchDialog(this); - // pre-hide all the extraneous elements mBadgeLabel.setVisibility(View.GONE); @@ -1673,15 +1673,56 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS } return result; } - + + /** + * The root element in the search bar layout. This is a custom view just to override + * the handling of the back button. + */ + public static class SearchBar extends LinearLayout { + + private SearchDialog mSearchDialog; + + public SearchBar(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public SearchBar(Context context) { + super(context); + } + + public void setSearchDialog(SearchDialog searchDialog) { + mSearchDialog = searchDialog; + } + + /** + * Overrides the handling of the back key to move back to the previous sources or dismiss + * the search dialog, instead of dismissing the input method. + */ + @Override + public boolean dispatchKeyEventPreIme(KeyEvent event) { + if (DBG) Log.d(LOG_TAG, "onKeyPreIme(" + event + ")"); + if (mSearchDialog != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { + if (event.getAction() == KeyEvent.ACTION_DOWN + && event.getRepeatCount() == 0) { + getKeyDispatcherState().startTracking(event, this); + return true; + } else if (event.getAction() == KeyEvent.ACTION_UP + && !event.isCanceled() && getKeyDispatcherState().isTracking(event)) { + mSearchDialog.onBackPressed(); + return true; + } + } + return super.dispatchKeyEventPreIme(event); + } + } + /** * Local subclass for AutoCompleteTextView. */ public static class SearchAutoComplete extends AutoCompleteTextView { private int mThreshold; - private SearchDialog mSearchDialog; - + public SearchAutoComplete(Context context) { super(context); mThreshold = getThreshold(); @@ -1697,10 +1738,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS mThreshold = getThreshold(); } - private void setSearchDialog(SearchDialog searchDialog) { - mSearchDialog = searchDialog; - } - @Override public void setThreshold(int threshold) { super.setThreshold(threshold); @@ -1754,46 +1791,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS return mThreshold <= 0 || super.enoughToFilter(); } - /** - * {@link AutoCompleteTextView#onKeyPreIme(int, KeyEvent)}) dismisses the drop-down on BACK, - * so we must override this method to modify the BACK behavior. - */ - @Override - public boolean onKeyPreIme(int keyCode, KeyEvent event) { - if (DBG) Log.d(LOG_TAG, "onKeyPreIme(" + keyCode + "," + event + ")"); - if (mSearchDialog.mSearchable == null) { - return false; - } - if (keyCode == KeyEvent.KEYCODE_BACK) { - if (event.getAction() == KeyEvent.ACTION_DOWN - && event.getRepeatCount() == 0) { - if (mSearchDialog.hasPreviousComponent() || isDismissingKeyboardPointless()) { - getKeyDispatcherState().startTracking(event, this); - return true; - } - } else if (event.getAction() == KeyEvent.ACTION_UP - && event.isTracking() && !event.isCanceled()) { - if (mSearchDialog.backToPreviousComponent()) { - return true; - } else if (isDismissingKeyboardPointless()) { - mSearchDialog.cancel(); - return true; - } - } - } - return false; - } - - // If the drop-down obscures the keyboard, or if the drop-down shows all suggestions, - // dismissing the keyboard is pointless, so we dismiss the entire dialog instead. - private boolean isDismissingKeyboardPointless() { - return (isInputMethodNotNeeded() || getDropDownChildCount() >= getAdapterCount()); - } - - private int getAdapterCount() { - final ListAdapter adapter = getAdapter(); - return adapter == null ? 0 : adapter.getCount(); - } } @Override diff --git a/core/res/res/layout/search_bar.xml b/core/res/res/layout/search_bar.xml index 13e66aad0d258..964af9ba7d3fb 100644 --- a/core/res/res/layout/search_bar.xml +++ b/core/res/res/layout/search_bar.xml @@ -17,8 +17,9 @@ ** limitations under the License. */ --> - - +