summaryrefslogtreecommitdiffstats
path: root/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java
diff options
context:
space:
mode:
Diffstat (limited to 'actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java')
-rw-r--r--actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java644
1 files changed, 644 insertions, 0 deletions
diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java
new file mode 100644
index 000000000..d13c6cea9
--- /dev/null
+++ b/actionbarsherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java
@@ -0,0 +1,644 @@
+package com.actionbarsherlock.internal.widget;
+
+import com.actionbarsherlock.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.database.DataSetObserver;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.view.ContextThemeWrapper;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.MeasureSpec;
+import android.view.View.OnTouchListener;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.AbsListView;
+import android.widget.AdapterView;
+import android.widget.LinearLayout;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.PopupWindow;
+
+/**
+ * A proxy between pre- and post-Honeycomb implementations of this class.
+ */
+public class IcsListPopupWindow {
+ /**
+ * This value controls the length of time that the user
+ * must leave a pointer down without scrolling to expand
+ * the autocomplete dropdown list to cover the IME.
+ */
+ private static final int EXPAND_LIST_TIMEOUT = 250;
+
+ private Context mContext;
+ private PopupWindow mPopup;
+ private ListAdapter mAdapter;
+ private DropDownListView mDropDownList;
+
+ private int mDropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT;
+ private int mDropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT;
+ private int mDropDownHorizontalOffset;
+ private int mDropDownVerticalOffset;
+ private boolean mDropDownVerticalOffsetSet;
+
+ private int mListItemExpandMaximum = Integer.MAX_VALUE;
+
+ private View mPromptView;
+ private int mPromptPosition = POSITION_PROMPT_ABOVE;
+
+ private DataSetObserver mObserver;
+
+ private View mDropDownAnchorView;
+
+ private Drawable mDropDownListHighlight;
+
+ private AdapterView.OnItemClickListener mItemClickListener;
+ private AdapterView.OnItemSelectedListener mItemSelectedListener;
+
+ private final ResizePopupRunnable mResizePopupRunnable = new ResizePopupRunnable();
+ private final PopupTouchInterceptor mTouchInterceptor = new PopupTouchInterceptor();
+ private final PopupScrollListener mScrollListener = new PopupScrollListener();
+ private final ListSelectorHider mHideSelector = new ListSelectorHider();
+
+ private Handler mHandler = new Handler();
+
+ private Rect mTempRect = new Rect();
+
+ private boolean mModal;
+
+ public static final int POSITION_PROMPT_ABOVE = 0;
+ public static final int POSITION_PROMPT_BELOW = 1;
+
+ public IcsListPopupWindow(Context context) {
+ this(context, null, R.attr.listPopupWindowStyle);
+ }
+
+ public IcsListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr) {
+ mContext = context;
+ mPopup = new PopupWindow(context, attrs, defStyleAttr);
+ mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
+ }
+
+ public IcsListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ mContext = context;
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
+ Context wrapped = new ContextThemeWrapper(context, defStyleRes);
+ mPopup = new PopupWindow(wrapped, attrs, defStyleAttr);
+ } else {
+ mPopup = new PopupWindow(context, attrs, defStyleAttr, defStyleRes);
+ }
+ mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
+ }
+
+ public void setAdapter(ListAdapter adapter) {
+ if (mObserver == null) {
+ mObserver = new PopupDataSetObserver();
+ } else if (mAdapter != null) {
+ mAdapter.unregisterDataSetObserver(mObserver);
+ }
+ mAdapter = adapter;
+ if (mAdapter != null) {
+ adapter.registerDataSetObserver(mObserver);
+ }
+
+ if (mDropDownList != null) {
+ mDropDownList.setAdapter(mAdapter);
+ }
+ }
+
+ public void setPromptPosition(int position) {
+ mPromptPosition = position;
+ }
+
+ public void setModal(boolean modal) {
+ mModal = true;
+ mPopup.setFocusable(modal);
+ }
+
+ public void setBackgroundDrawable(Drawable d) {
+ mPopup.setBackgroundDrawable(d);
+ }
+
+ public void setAnchorView(View anchor) {
+ mDropDownAnchorView = anchor;
+ }
+
+ public void setHorizontalOffset(int offset) {
+ mDropDownHorizontalOffset = offset;
+ }
+
+ public void setVerticalOffset(int offset) {
+ mDropDownVerticalOffset = offset;
+ mDropDownVerticalOffsetSet = true;
+ }
+
+ public void setContentWidth(int width) {
+ Drawable popupBackground = mPopup.getBackground();
+ if (popupBackground != null) {
+ popupBackground.getPadding(mTempRect);
+ mDropDownWidth = mTempRect.left + mTempRect.right + width;
+ } else {
+ mDropDownWidth = width;
+ }
+ }
+
+ public void setOnItemClickListener(AdapterView.OnItemClickListener clickListener) {
+ mItemClickListener = clickListener;
+ }
+
+ public void show() {
+ int height = buildDropDown();
+
+ int widthSpec = 0;
+ 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;
+ }
+
+ final int listContent = /*mDropDownList.*/measureHeightOfChildren(MeasureSpec.UNSPECIFIED,
+ 0, -1/*ListView.NO_POSITION*/, maxHeight - otherHeights, -1);
+ // add padding only if the list has items in it, that way we don't show
+ // the popup if it is not needed
+ if (listContent > 0) otherHeights += padding;
+
+ return listContent + otherHeights;
+ }
+
+ private int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) {
+ final Rect displayFrame = new Rect();
+ anchor.getWindowVisibleDisplayFrame(displayFrame);
+
+ final int[] anchorPos = new int[2];
+ anchor.getLocationOnScreen(anchorPos);
+
+ int bottomEdge = displayFrame.bottom;
+ if (ignoreBottomDecorations) {
+ Resources res = anchor.getContext().getResources();
+ bottomEdge = res.getDisplayMetrics().heightPixels;
+ }
+ 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
+ int returnedHeight = Math.max(distanceToBottom, distanceToTop);
+ if (mPopup.getBackground() != null) {
+ mPopup.getBackground().getPadding(mTempRect);
+ returnedHeight -= mTempRect.top + mTempRect.bottom;
+ }
+
+ return returnedHeight;
+ }
+
+ private int measureHeightOfChildren(int widthMeasureSpec, int startPosition, int endPosition,
+ final int maxHeight, int disallowPartialChildPosition) {
+
+ final ListAdapter adapter = mAdapter;
+ if (adapter == null) {
+ return mDropDownList.getListPaddingTop() + mDropDownList.getListPaddingBottom();
+ }
+
+ // Include the padding of the list
+ int returnedHeight = mDropDownList.getListPaddingTop() + mDropDownList.getListPaddingBottom();
+ final int dividerHeight = ((mDropDownList.getDividerHeight() > 0) && mDropDownList.getDivider() != null) ? mDropDownList.getDividerHeight() : 0;
+ // The previous height value that was less than maxHeight and contained
+ // no partial children
+ int prevHeightWithoutPartialChild = 0;
+ int i;
+ View child;
+
+ // mItemCount - 1 since endPosition parameter is inclusive
+ endPosition = (endPosition == -1/*NO_POSITION*/) ? adapter.getCount() - 1 : endPosition;
+
+ for (i = startPosition; i <= endPosition; ++i) {
+ child = mAdapter.getView(i, null, mDropDownList);
+ if (mDropDownList.getCacheColorHint() != 0) {
+ child.setDrawingCacheBackgroundColor(mDropDownList.getCacheColorHint());
+ }
+
+ measureScrapChild(child, i, widthMeasureSpec);
+
+ if (i > 0) {
+ // Count the divider for all but one child
+ returnedHeight += dividerHeight;
+ }
+
+ returnedHeight += child.getMeasuredHeight();
+
+ if (returnedHeight >= maxHeight) {
+ // We went over, figure out which height to return. If returnedHeight > maxHeight,
+ // then the i'th position did not fit completely.
+ return (disallowPartialChildPosition >= 0) // Disallowing is enabled (> -1)
+ && (i > disallowPartialChildPosition) // We've past the min pos
+ && (prevHeightWithoutPartialChild > 0) // We have a prev height
+ && (returnedHeight != maxHeight) // i'th child did not fit completely
+ ? prevHeightWithoutPartialChild
+ : maxHeight;
+ }
+
+ if ((disallowPartialChildPosition >= 0) && (i >= disallowPartialChildPosition)) {
+ prevHeightWithoutPartialChild = returnedHeight;
+ }
+ }
+
+ // At this point, we went through the range of children, and they each
+ // completely fit, so return the returnedHeight
+ return returnedHeight;
+ }
+ private void measureScrapChild(View child, int position, int widthMeasureSpec) {
+ ListView.LayoutParams p = (ListView.LayoutParams) child.getLayoutParams();
+ if (p == null) {
+ p = new ListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT, 0);
+ child.setLayoutParams(p);
+ }
+ //XXX p.viewType = mAdapter.getItemViewType(position);
+ //XXX p.forceAdd = true;
+
+ int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
+ mDropDownList.getPaddingLeft() + mDropDownList.getPaddingRight(), p.width);
+ int lpHeight = p.height;
+ int childHeightSpec;
+ if (lpHeight > 0) {
+ childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
+ } else {
+ childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ }
+ child.measure(childWidthSpec, childHeightSpec);
+ }
+
+ private static class DropDownListView extends ListView {
+ /*
+ * WARNING: This is a workaround for a touch mode issue.
+ *
+ * Touch mode is propagated lazily to windows. This causes problems in
+ * the following scenario:
+ * - Type something in the AutoCompleteTextView and get some results
+ * - Move down with the d-pad to select an item in the list
+ * - Move up with the d-pad until the selection disappears
+ * - Type more text in the AutoCompleteTextView *using the soft keyboard*
+ * and get new results; you are now in touch mode
+ * - The selection comes back on the first item in the list, even though
+ * the list is supposed to be in touch mode
+ *
+ * Using the soft keyboard triggers the touch mode change but that change
+ * is propagated to our window only after the first list layout, therefore
+ * after the list attempts to resurrect the selection.
+ *
+ * The trick to work around this issue is to pretend the list is in touch
+ * mode when we know that the selection should not appear, that is when
+ * we know the user moved the selection away from the list.
+ *
+ * This boolean is set to true whenever we explicitly hide the list's
+ * selection and reset to false whenever we know the user moved the
+ * selection back to the list.
+ *
+ * When this boolean is true, isInTouchMode() returns true, otherwise it
+ * returns super.isInTouchMode().
+ */
+ private boolean mListSelectionHidden;
+
+ private boolean mHijackFocus;
+
+ public DropDownListView(Context context, boolean hijackFocus) {
+ super(context, null, /*com.android.internal.*/R.attr.dropDownListViewStyle);
+ mHijackFocus = hijackFocus;
+ // TODO: Add an API to control this
+ setCacheColorHint(0); // Transparent, since the background drawable could be anything.
+ }
+
+ //XXX @Override
+ //View obtainView(int position, boolean[] isScrap) {
+ // View view = super.obtainView(position, isScrap);
+
+ // if (view instanceof TextView) {
+ // ((TextView) view).setHorizontallyScrolling(true);
+ // }
+
+ // return view;
+ //}
+
+ @Override
+ public boolean isInTouchMode() {
+ // WARNING: Please read the comment where mListSelectionHidden is declared
+ return (mHijackFocus && mListSelectionHidden) || super.isInTouchMode();
+ }
+
+ @Override
+ public boolean hasWindowFocus() {
+ return mHijackFocus || super.hasWindowFocus();
+ }
+
+ @Override
+ public boolean isFocused() {
+ return mHijackFocus || super.isFocused();
+ }
+
+ @Override
+ public boolean hasFocus() {
+ return mHijackFocus || super.hasFocus();
+ }
+ }
+
+ private class PopupDataSetObserver extends DataSetObserver {
+ @Override
+ public void onChanged() {
+ if (isShowing()) {
+ // Resize the popup to fit new content
+ show();
+ }
+ }
+
+ @Override
+ public void onInvalidated() {
+ dismiss();
+ }
+ }
+
+ private class ListSelectorHider implements Runnable {
+ public void run() {
+ clearListSelection();
+ }
+ }
+
+ private class ResizePopupRunnable implements Runnable {
+ public void run() {
+ if (mDropDownList != null && mDropDownList.getCount() > mDropDownList.getChildCount() &&
+ mDropDownList.getChildCount() <= mListItemExpandMaximum) {
+ mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
+ show();
+ }
+ }
+ }
+
+ private class PopupTouchInterceptor implements OnTouchListener {
+ public boolean onTouch(View v, MotionEvent event) {
+ final int action = event.getAction();
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+
+ if (action == MotionEvent.ACTION_DOWN &&
+ mPopup != null && mPopup.isShowing() &&
+ (x >= 0 && x < mPopup.getWidth() && y >= 0 && y < mPopup.getHeight())) {
+ mHandler.postDelayed(mResizePopupRunnable, EXPAND_LIST_TIMEOUT);
+ } else if (action == MotionEvent.ACTION_UP) {
+ mHandler.removeCallbacks(mResizePopupRunnable);
+ }
+ return false;
+ }
+ }
+
+ private class PopupScrollListener implements ListView.OnScrollListener {
+ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+ int totalItemCount) {
+
+ }
+
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ if (scrollState == SCROLL_STATE_TOUCH_SCROLL &&
+ !isInputMethodNotNeeded() && mPopup.getContentView() != null) {
+ mHandler.removeCallbacks(mResizePopupRunnable);
+ mResizePopupRunnable.run();
+ }
+ }
+ }
+}