diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index 8fc24472207ef..0aa5975d7faf5 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -171,7 +171,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS // having windows anchored by their parent but not clipped by them. ViewGroup.LayoutParams.FILL_PARENT); WindowManager.LayoutParams lp = theWindow.getAttributes(); - lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE; + lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; theWindow.setAttributes(lp); // get the view elements for local access @@ -528,6 +528,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS mSearchAutoComplete.setDropDownAnimationStyle(0); // no animation mSearchAutoComplete.setThreshold(mSearchable.getSuggestThreshold()); + // TODO: Use different dropdown background resource for in-app search. if (mGlobalSearchMode) { mSearchAutoComplete.setDropDownAlwaysVisible(true); // fill space until results come in mSearchAutoComplete.setDropDownDismissedOnCompletion(false); diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 8da7c6b983db5..bfc5f081d4627 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -126,6 +126,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe // Indicates whether this AutoCompleteTextView is attached to a window or not // The widget is attached to a window when mAttachCount > 0 private int mAttachCount; + + private AutoCompleteTextView.PassThroughClickListener mPassThroughClickListener; public AutoCompleteTextView(Context context) { this(context, null); @@ -186,6 +188,28 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe setFocusable(true); addTextChangedListener(new MyWatcher()); + + mPassThroughClickListener = new PassThroughClickListener(); + super.setOnClickListener(mPassThroughClickListener); + } + + @Override + public void setOnClickListener(OnClickListener listener) { + mPassThroughClickListener.mWrapped = listener; + } + + /** + * Private hook into the on click event, dispatched from {@link PassThroughClickListener} + */ + private void onClickImpl() { + // if drop down should always visible, bring it back in front of the soft + // keyboard when the user touches the text field + if (mDropDownAlwaysVisible + && mPopup.isShowing() + && mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED) { + mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); + showDropDown(); + } } /** @@ -1130,9 +1154,14 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe } } - // Max height available on the screen for a popup - final int maxHeight = - mPopup.getMaxAvailableHeight(getDropDownAnchorView(), mDropDownVerticalOffset); + // Max height available on the screen for a popup. If this AutoCompleteTextView has + // the dropDownAlwaysVisible attribute, and the input method is not currently required, + // we then we ask for the height ignoring any bottom decorations like the input method. + // Otherwise we respect the input method. + boolean ignoreBottomDecorations = mDropDownAlwaysVisible && + mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; + final int maxHeight = mPopup.getMaxAvailableHeight( + getDropDownAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations); final int measuredHeight = mDropDownList.measureHeightOfChildren(MeasureSpec.UNSPECIFIED, 0, ListView.NO_POSITION, maxHeight - otherHeights, 2) + otherHeights; @@ -1214,7 +1243,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); - mPopup.update(); + showDropDown(); } return false; } @@ -1353,4 +1382,21 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe */ CharSequence fixText(CharSequence invalidText); } + + /** + * Allows us a private hook into the on click event without preventing users from setting + * their own click listener. + */ + private class PassThroughClickListener implements OnClickListener { + + private View.OnClickListener mWrapped; + + /** {@inheritDoc} */ + public void onClick(View v) { + onClickImpl(); + + if (mWrapped != null) mWrapped.onClick(v); + } + } + } diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index 2c9714e318ba3..acd25ee50fa6a 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -25,6 +25,7 @@ import android.view.WindowManager; import android.view.Gravity; import android.view.ViewGroup; import android.view.ViewTreeObserver; +import android.view.WindowManagerImpl; import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.View.OnTouchListener; import android.graphics.PixelFormat; @@ -948,14 +949,38 @@ public class PopupWindow { * shown. */ public int getMaxAvailableHeight(View anchor, int yOffset) { + return getMaxAvailableHeight(anchor, yOffset, false); + } + + /** + * Returns the maximum height that is available for the popup to be + * completely shown, optionally ignoring any bottom decorations such as + * the input method. It is recommended that this height be the maximum for + * the popup's height, otherwise it is possible that the popup will be + * clipped. + * + * @param anchor The view on which the popup window must be anchored. + * @param yOffset y offset from the view's bottom edge + * @param ignoreBottomDecorations if true, the height returned will be + * all the way to the bottom of the display, ignoring any + * bottom decorations + * @return The maximum available height for the popup to be completely + * shown. + * + * @hide Pending API council approval. + */ + public int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) { final Rect displayFrame = new Rect(); anchor.getWindowVisibleDisplayFrame(displayFrame); final int[] anchorPos = mDrawingLocation; anchor.getLocationOnScreen(anchorPos); - final int distanceToBottom = displayFrame.bottom - - (anchorPos[1] + anchor.getHeight()) - yOffset; + int bottomEdge = displayFrame.bottom; + if (ignoreBottomDecorations) { + bottomEdge = WindowManagerImpl.getDefault().getDefaultDisplay().getHeight(); + } + final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset; final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset; // anchorPos[1] is distance from anchor to top of screen @@ -1116,7 +1141,7 @@ public class PopupWindow { p.flags = newFlags; update = true; } - + if (update) { mWindowManager.updateViewLayout(mPopupView, p); }