From e29f064383cbc745c8605c707000ab4e16ee0aac Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Tue, 23 Jun 2009 21:27:02 -0700 Subject: [PATCH] Fixes #1905761. Updates the height of ACTV's drop down whenever the IME changes. --- api/current.xml | 46 +++++++--- .../android/widget/AutoCompleteTextView.java | 90 ++++++++++++++++--- core/java/android/widget/PopupWindow.java | 13 ++- core/res/res/layout/search_bar.xml | 1 + core/res/res/values/attrs.xml | 10 +++ core/res/res/values/public.xml | 3 +- 6 files changed, 133 insertions(+), 30 deletions(-) diff --git a/api/current.xml b/api/current.xml index 595a9f042fd54..f5bcb5c424b36 100644 --- a/api/current.xml +++ b/api/current.xml @@ -3485,17 +3485,6 @@ visibility="public" > - - + + + + + + + + Returns the current height for the auto-complete drop down list. This can + * be a fixed height, or {@link ViewGroup.LayoutParams#FILL_PARENT} to fill + * the screen, or {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the height + * of the drop down's content.

+ * + * @return the height for the drop down list + * + * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight + */ + public int getDropDownHeight() { + return mDropDownHeight; + } + + /** + *

Sets the current height for the auto-complete drop down list. This can + * be a fixed height, or {@link ViewGroup.LayoutParams#FILL_PARENT} to fill + * the screen, or {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the height + * of the drop down's content.

+ * + * @param height the height to use + * + * @attr ref android.R.styleable#AutoCompleteTextView_dropDownHeight + */ + public void setDropDownHeight(int height) { + mDropDownHeight = height; + } /** *

Returns the id for the view that the auto-complete drop down list is anchored to.

@@ -635,7 +667,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe // event to prevent focus from moving. clearListSelection(); mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); - mPopup.update(); + showDropDown(); return true; } else { // WARNING: Please read the comment where mListSelectionHidden @@ -655,7 +687,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe // by ensuring it has focus and getting its window out // of touch mode. mDropDownList.requestFocusFromTouch(); - mPopup.update(); + showDropDown(); switch (keyCode) { // avoid passing the focus from the text view to the @@ -1052,8 +1084,13 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe */ public void showDropDown() { int height = buildDropDown(); + + int widthSpec = 0; + int heightSpec = 0; + + boolean noInputMethod = mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; + if (mPopup.isShowing()) { - int widthSpec; if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) { // The call to PopupWindow's update method below can accept -1 for any // value you do not want to update. @@ -1063,20 +1100,51 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe } else { widthSpec = mDropDownWidth; } + + if (mDropDownHeight == ViewGroup.LayoutParams.FILL_PARENT) { + // The call to PopupWindow's update method below can accept -1 for any + // value you do not want to update. + heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.FILL_PARENT; + if (noInputMethod) { + mPopup.setWindowLayoutMode( + mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT ? + ViewGroup.LayoutParams.FILL_PARENT : 0, 0); + } else { + mPopup.setWindowLayoutMode( + mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT ? + ViewGroup.LayoutParams.FILL_PARENT : 0, + ViewGroup.LayoutParams.FILL_PARENT); + } + } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { + heightSpec = height; + } else { + heightSpec = mDropDownHeight; + } + mPopup.update(getDropDownAnchorView(), mDropDownHorizontalOffset, - mDropDownVerticalOffset, widthSpec, height); + mDropDownVerticalOffset, widthSpec, heightSpec); } else { if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) { - mPopup.setWindowLayoutMode(ViewGroup.LayoutParams.FILL_PARENT, 0); + widthSpec = ViewGroup.LayoutParams.FILL_PARENT; } else { - mPopup.setWindowLayoutMode(0, 0); if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { mPopup.setWidth(getDropDownAnchorView().getWidth()); } else { mPopup.setWidth(mDropDownWidth); } } - mPopup.setHeight(height); + + if (mDropDownHeight == ViewGroup.LayoutParams.FILL_PARENT) { + heightSpec = ViewGroup.LayoutParams.FILL_PARENT; + } else { + if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { + mPopup.setHeight(height); + } else { + mPopup.setHeight(mDropDownHeight); + } + } + + mPopup.setWindowLayoutMode(widthSpec, heightSpec); mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); // use outside touchable to dismiss drop down when touching outside of it, so @@ -1195,10 +1263,12 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe final int maxHeight = mPopup.getMaxAvailableHeight( getDropDownAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations); - final int measuredHeight = mDropDownList.measureHeightOfChildren(MeasureSpec.UNSPECIFIED, - 0, ListView.NO_POSITION, maxHeight - otherHeights, 2) + otherHeights; + if (mDropDownAlwaysVisible) { + return maxHeight; + } - return mDropDownAlwaysVisible ? maxHeight : measuredHeight; + return mDropDownList.measureHeightOfChildren(MeasureSpec.UNSPECIFIED, + 0, ListView.NO_POSITION, maxHeight - otherHeights, 2) + otherHeights; } private View getHintView(Context context) { diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index b188c31cc35d2..bd6edfb54afef 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -49,7 +49,7 @@ import java.lang.ref.WeakReference; */ public class PopupWindow { /** - * Mode for {@link #setInputMethodMode(int): the requirements for the + * Mode for {@link #setInputMethodMode(int)}: the requirements for the * input method should be based on the focusability of the popup. That is * if it is focusable than it needs to work with the input method, else * it doesn't. @@ -57,16 +57,15 @@ public class PopupWindow { public static final int INPUT_METHOD_FROM_FOCUSABLE = 0; /** - * Mode for {@link #setInputMethodMode(int): this popup always needs to + * Mode for {@link #setInputMethodMode(int)}: this popup always needs to * work with an input method, regardless of whether it is focusable. This * means that it will always be displayed so that the user can also operate * the input method while it is shown. */ - public static final int INPUT_METHOD_NEEDED = 1; /** - * Mode for {@link #setInputMethodMode(int): this popup never needs to + * Mode for {@link #setInputMethodMode(int)}: this popup never needs to * work with an input method, regardless of whether it is focusable. This * means that it will always be displayed to use as much space on the * screen as needed, regardless of whether this covers the input method. @@ -1131,8 +1130,7 @@ public class PopupWindow { return; } - WindowManager.LayoutParams p = (WindowManager.LayoutParams) - mPopupView.getLayoutParams(); + WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams(); boolean update = force; @@ -1219,8 +1217,7 @@ public class PopupWindow { registerForScrollChanged(anchor, xoff, yoff); } - WindowManager.LayoutParams p = (WindowManager.LayoutParams) - mPopupView.getLayoutParams(); + WindowManager.LayoutParams p = (WindowManager.LayoutParams) mPopupView.getLayoutParams(); if (updateDimension) { if (width == -1) { diff --git a/core/res/res/layout/search_bar.xml b/core/res/res/layout/search_bar.xml index 54ab6de6184c9..13e66aad0d258 100644 --- a/core/res/res/layout/search_bar.xml +++ b/core/res/res/layout/search_bar.xml @@ -76,6 +76,7 @@ android:ellipsize="end" android:inputType="text|textAutoComplete" android:dropDownWidth="fill_parent" + android:dropDownHeight="fill_parent" android:dropDownAnchor="@id/search_plate" android:dropDownVerticalOffset="-9dip" android:popupBackground="@android:drawable/search_dropdown_background" diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 23ab573f812fd..e978ef50e15e7 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -1998,6 +1998,16 @@ + + + + + + + diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index e5a58b15e4a44..4634b50da72a7 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1116,7 +1116,8 @@ - + +