int heightSpec = 0; boolean noInputMethod = isInputMethodNotNeeded(); //XXX mPopup.setAllowScrollingAnchorParent(!noInputMethod); if (mPopup.isShowing()) { if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { // The call to PopupWindow's update method below can accept -1 for any // value you do not want to update. widthSpec = -1; } else if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { widthSpec = mDropDownAnchorView.getWidth(); } else { widthSpec = mDropDownWidth; } if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_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.MATCH_PARENT; if (noInputMethod) { mPopup.setWindowLayoutMode( mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? ViewGroup.LayoutParams.MATCH_PARENT : 0, 0); } else { mPopup.setWindowLayoutMode( mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ? ViewGroup.LayoutParams.MATCH_PARENT : 0, ViewGroup.LayoutParams.MATCH_PARENT); } } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { heightSpec = height; } else { heightSpec = mDropDownHeight; } mPopup.setOutsideTouchable(true); mPopup.update(mDropDownAnchorView, mDropDownHorizontalOffset, mDropDownVerticalOffset, widthSpec, heightSpec); } else { if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { widthSpec = ViewGroup.LayoutParams.MATCH_PARENT; } else { if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { mPopup.setWidth(mDropDownAnchorView.getWidth()); } else { mPopup.setWidth(mDropDownWidth); } } if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { heightSpec = ViewGroup.LayoutParams.MATCH_PARENT; } else { if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { mPopup.setHeight(height); } else { mPopup.setHeight(mDropDownHeight); } } mPopup.setWindowLayoutMode(widthSpec, heightSpec); //XXX mPopup.setClipToScreenEnabled(true); // use outside touchable to dismiss drop down when touching outside of it, so // only set this if the dropdown is not always visible mPopup.setOutsideTouchable(true); mPopup.setTouchInterceptor(mTouchInterceptor); mPopup.showAsDropDown(mDropDownAnchorView, mDropDownHorizontalOffset, mDropDownVerticalOffset); mDropDownList.setSelection(ListView.INVALID_POSITION); if (!mModal || mDropDownList.isInTouchMode()) { clearListSelection(); } if (!mModal) { mHandler.post(mHideSelector); } } } public void dismiss() { mPopup.dismiss(); if (mPromptView != null) { final ViewParent parent = mPromptView.getParent(); if (parent instanceof ViewGroup) { final ViewGroup group = (ViewGroup) parent; group.removeView(mPromptView); } } mPopup.setContentView(null); mDropDownList = null; mHandler.removeCallbacks(mResizePopupRunnable); } public void setOnDismissListener(PopupWindow.OnDismissListener listener) { mPopup.setOnDismissListener(listener); } public void setInputMethodMode(int mode) { mPopup.setInputMethodMode(mode); } public void clearListSelection() { final DropDownListView list = mDropDownList; if (list != null) { // WARNING: Please read the comment where mListSelectionHidden is declared list.mListSelectionHidden = true; //XXX list.hideSelector(); list.requestLayout(); } } public boolean isShowing() { return mPopup.isShowing(); } private boolean isInputMethodNotNeeded() { return mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; } public ListView getListView() { return mDropDownList; } private int buildDropDown() { ViewGroup dropDownView; int otherHeights = 0; if (mDropDownList == null) { Context context = mContext; mDropDownList = new DropDownListView(context, !mModal); if (mDropDownListHighlight != null) { mDropDownList.setSelector(mDropDownListHighlight); } mDropDownList.setAdapter(mAdapter); mDropDownList.setOnItemClickListener(mItemClickListener); mDropDownList.setFocusable(true); mDropDownList.setFocusableInTouchMode(true); mDropDownList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { if (position != -1) { DropDownListView dropDownList = mDropDownList; if (dropDownList != null) { dropDownList.mListSelectionHidden = false; } } } public void onNothingSelected(AdapterView<?> parent) { } }); mDropDownList.setOnScrollListener(mScrollListener); if (mItemSelectedListener != null) { mDropDownList.setOnItemSelectedListener(mItemSelectedListener); } dropDownView = mDropDownList; View hintView = mPromptView; if (hintView != null) { // if an hint has been specified, we accomodate more space for it and // add a text view in the drop down menu, at the bottom of the list LinearLayout hintContainer = new LinearLayout(context); hintContainer.setOrientation(LinearLayout.VERTICAL); LinearLayout.LayoutParams hintParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, 0, 1.0f ); switch (mPromptPosition) { case POSITION_PROMPT_BELOW: hintContainer.addView(dropDownView, hintParams); hintContainer.addView(hintView); break; case POSITION_PROMPT_ABOVE: hintContainer.addView(hintView); hintContainer.addView(dropDownView, hintParams); break; default: break; } // measure the hint's height to find how much more vertical space // we need to add to the drop down's height int widthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.AT_MOST); int heightSpec = MeasureSpec.UNSPECIFIED; hintView.measure(widthSpec, heightSpec); hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams(); otherHeights = hintView.getMeasuredHeight() + hintParams.topMargin + hintParams.bottomMargin; dropDownView = hintContainer; } mPopup.setContentView(dropDownView); } else { dropDownView = (ViewGroup) mPopup.getContentView(); final View view = mPromptView; if (view != null) { LinearLayout.LayoutParams hintParams = (LinearLayout.LayoutParams) view.getLayoutParams(); otherHeights = view.getMeasuredHeight() + hintParams.topMargin + hintParams.bottomMargin; } } // getMaxAvailableHeight() subtracts the padding, so we put it back // to get the available height for the whole window int padding = 0; Drawable background = mPopup.getBackground(); if (background != null) { background.getPadding(mTempRect); padding = mTempRect.top + mTempRect.bottom; // If we don't have an explicit vertical offset, determine one from the window // background so that content will line up. if (!mDropDownVerticalOffsetSet) { mDropDownVerticalOffset = -mTempRect.top; } } // Max height available on the screen for a popup. boolean ignoreBottomDecorations = mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; final int maxHeight = /*mPopup.*/getMaxAvailableHeight( mDropDownAnchorView, mDropDownVerticalOffset, ignoreBottomDecorations); if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) { return maxHeight + padding;