ListPopupWindow.java revision da10fdd1400ecfd8d7f2e55651dd528d0614dfc5
13565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani/*
23565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Copyright (C) 2010 The Android Open Source Project
33565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani *
43565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Licensed under the Apache License, Version 2.0 (the "License");
53565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * you may not use this file except in compliance with the License.
63565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * You may obtain a copy of the License at
73565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani *
83565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani *      http://www.apache.org/licenses/LICENSE-2.0
93565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani *
103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Unless required by applicable law or agreed to in writing, software
113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * distributed under the License is distributed on an "AS IS" BASIS,
123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * See the License for the specific language governing permissions and
143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * limitations under the License.
153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */
163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
17da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownpackage android.support.v7.internal.widget;
183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.content.Context;
203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.content.res.Resources;
213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.database.DataSetObserver;
223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.graphics.Rect;
233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.graphics.drawable.Drawable;
243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.os.Handler;
25da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.appcompat.R;
263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.text.TextUtils;
273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.util.AttributeSet;
283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.util.Log;
293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.util.SparseArray;
303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.KeyEvent;
313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.MotionEvent;
323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.View;
333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.View.MeasureSpec;
343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.View.OnTouchListener;
353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.ViewGroup;
363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.ViewParent;
373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.widget.*;
383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport java.lang.reflect.Field;
403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport java.util.ArrayList;
413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport java.util.List;
423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport java.util.Locale;
433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani/**
4520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * A ListPopupWindow anchors itself to a host view and displays a list of choices.
463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani *
4720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * <p>ListPopupWindow contains a number of tricky behaviors surrounding positioning, scrolling
4820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * parents to fit the dropdown, interacting sanely with the IME if present, and others.
493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani *
503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see android.widget.AutoCompleteTextView
513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see android.widget.Spinner
523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */
533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewanipublic class ListPopupWindow {
5420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private static final String TAG = "ListPopupWindow";
563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private static final boolean DEBUG = false;
573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
5920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * This value controls the length of time that the user must leave a pointer down without
6020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * scrolling to expand the autocomplete dropdown list to cover the IME.
613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private static final int EXPAND_LIST_TIMEOUT = 250;
633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private Context mContext;
653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private PopupWindow mPopup;
663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private ListAdapter mAdapter;
673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private DropDownListView mDropDownList;
683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private int mDropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT;
703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private int mDropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT;
713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private int mDropDownHorizontalOffset;
723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private int mDropDownVerticalOffset;
733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private boolean mDropDownVerticalOffsetSet;
743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private boolean mDropDownAlwaysVisible = false;
763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private boolean mForceIgnoreOutsideTouch = false;
773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    int mListItemExpandMaximum = Integer.MAX_VALUE;
783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private View mPromptView;
803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private int mPromptPosition = POSITION_PROMPT_ABOVE;
813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private DataSetObserver mObserver;
833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private View mDropDownAnchorView;
853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private Drawable mDropDownListHighlight;
873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private AdapterView.OnItemClickListener mItemClickListener;
893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private AdapterView.OnItemSelectedListener mItemSelectedListener;
903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private final ResizePopupRunnable mResizePopupRunnable = new ResizePopupRunnable();
923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private final PopupTouchInterceptor mTouchInterceptor = new PopupTouchInterceptor();
933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private final PopupScrollListener mScrollListener = new PopupScrollListener();
943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private final ListSelectorHider mHideSelector = new ListSelectorHider();
953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private Runnable mShowDropDownRunnable;
963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private Handler mHandler = new Handler();
983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private Rect mTempRect = new Rect();
1003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private boolean mModal;
1023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private int mLayoutDirection;
1043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
1063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * The provided prompt view should appear above list content.
1073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
1083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #setPromptPosition(int)
1093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #getPromptPosition()
1103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #setPromptView(View)
1113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
1123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public static final int POSITION_PROMPT_ABOVE = 0;
1133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
1153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * The provided prompt view should appear below list content.
1163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
1173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #setPromptPosition(int)
1183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #getPromptPosition()
1193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #setPromptView(View)
1203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
1213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public static final int POSITION_PROMPT_BELOW = 1;
1223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
12420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Alias for {@link ViewGroup.LayoutParams#FILL_PARENT}. If used to specify a popup width, the
12520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * popup will match the width of the anchor view. If used to specify a popup height, the popup
12620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * will fill available space.
1273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
1283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public static final int FILL_PARENT = ViewGroup.LayoutParams.FILL_PARENT;
1293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
13120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Alias for {@link ViewGroup.LayoutParams#WRAP_CONTENT}. If used to specify a popup width, the
13220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * popup will use the width of its content.
1333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
1343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public static final int WRAP_CONTENT = ViewGroup.LayoutParams.WRAP_CONTENT;
1353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
13720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Mode for {@link #setInputMethodMode(int)}: the requirements for the input method should be
13820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * based on the focusability of the popup.  That is if it is focusable than it needs to work
13920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * with the input method, else it doesn't.
1403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
1413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public static final int INPUT_METHOD_FROM_FOCUSABLE = PopupWindow.INPUT_METHOD_FROM_FOCUSABLE;
1423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
14420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Mode for {@link #setInputMethodMode(int)}: this popup always needs to work with an input
14520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * method, regardless of whether it is focusable.  This means that it will always be displayed
14620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * so that the user can also operate the input method while it is shown.
1473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
1483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public static final int INPUT_METHOD_NEEDED = PopupWindow.INPUT_METHOD_NEEDED;
1493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
15120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Mode for {@link #setInputMethodMode(int)}: this popup never needs to work with an input
15220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * method, regardless of whether it is focusable.  This means that it will always be displayed
15320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * to use as much space on the screen as needed, regardless of whether this covers the input
15420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * method.
1553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
1563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public static final int INPUT_METHOD_NOT_NEEDED = PopupWindow.INPUT_METHOD_NOT_NEEDED;
1573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
15920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Create a new, empty popup window capable of displaying items from a ListAdapter. Backgrounds
16020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * should be set using {@link #setBackgroundDrawable(Drawable)}.
1613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
1623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param context Context used for contained views.
1633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
1643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public ListPopupWindow(Context context) {
165ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns        this(context, null, R.attr.listPopupWindowStyle);
1663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
1673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
16920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Create a new, empty popup window capable of displaying items from a ListAdapter. Backgrounds
17020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * should be set using {@link #setBackgroundDrawable(Drawable)}.
1713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
1723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param context Context used for contained views.
17320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param attrs   Attributes from inflating parent views used to style the popup.
1743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
1753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public ListPopupWindow(Context context, AttributeSet attrs) {
176ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns        this(context, attrs, R.attr.listPopupWindowStyle);
1773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
1783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
18020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Create a new, empty popup window capable of displaying items from a ListAdapter. Backgrounds
18120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * should be set using {@link #setBackgroundDrawable(Drawable)}.
1823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
18320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param context      Context used for contained views.
18420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param attrs        Attributes from inflating parent views used to style the popup.
1853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param defStyleAttr Default style attribute to use for popup content.
1863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
1873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr) {
1883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mContext = context;
189ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns        mPopup = new PopupWindow(context, attrs, defStyleAttr);
1903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
1913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        // Set the default layout direction to match the default locale one
1923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        final Locale locale = mContext.getResources().getConfiguration().locale;
1933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
194ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns    }
1953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
1963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
19720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Sets the adapter that provides the data and the views to represent the data in this popup
19820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * window.
1993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
2003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param adapter The adapter to use to create this window's content.
2013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
2023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setAdapter(ListAdapter adapter) {
2033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (mObserver == null) {
2043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mObserver = new PopupDataSetObserver();
2053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        } else if (mAdapter != null) {
2063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mAdapter.unregisterDataSetObserver(mObserver);
2073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
2083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mAdapter = adapter;
2093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (mAdapter != null) {
2103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            adapter.registerDataSetObserver(mObserver);
2113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
2123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
2133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (mDropDownList != null) {
2143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mDropDownList.setAdapter(mAdapter);
2153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
2163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
2173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
2183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
21920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Set where the optional prompt view should appear. The default is {@link
22020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * #POSITION_PROMPT_ABOVE}.
2213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
2223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param position A position constant declaring where the prompt should be displayed.
2233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #POSITION_PROMPT_ABOVE
2243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #POSITION_PROMPT_BELOW
2253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
2263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setPromptPosition(int position) {
2273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mPromptPosition = position;
2283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
2293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
2303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
2313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return Where the optional prompt view should appear.
2323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #POSITION_PROMPT_ABOVE
2333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #POSITION_PROMPT_BELOW
2343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
2353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public int getPromptPosition() {
2363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mPromptPosition;
2373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
2383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
2393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
2403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Set whether this window should be modal when shown.
2413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
24220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * <p>If a popup window is modal, it will receive all touch and key input. If the user touches
24320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * outside the popup window's content area the popup window will be dismissed.
2443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
2453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param modal {@code true} if the popup window should be modal, {@code false} otherwise.
2463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
2473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setModal(boolean modal) {
2483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mModal = true;
2493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mPopup.setFocusable(modal);
2503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
2513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
2523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
2533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Returns whether the popup window will be modal when shown.
2543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
2553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return {@code true} if the popup window will be modal, {@code false} otherwise.
2563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
2573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public boolean isModal() {
2583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mModal;
2593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
2603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
2613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
2623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Forces outside touches to be ignored. Normally if {@link #isDropDownAlwaysVisible()} is
26320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * false, we allow outside touch to dismiss the dropdown. If this is set to true, then we ignore
26420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * outside touch even when the drop down is not set to always visible.
2653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
2663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @hide Used only by AutoCompleteTextView to handle some internal special cases.
2673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
2683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setForceIgnoreOutsideTouch(boolean forceIgnoreOutsideTouch) {
2693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mForceIgnoreOutsideTouch = forceIgnoreOutsideTouch;
2703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
2713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
2723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
2733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Sets whether the drop-down should remain visible under certain conditions.
2743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
27520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * The drop-down will occupy the entire screen below {@link #getAnchorView} regardless of the
27620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * size or content of the list.  {@link #getBackground()} will fill any space that is not used
27720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * by the list.
2783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
2793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param dropDownAlwaysVisible Whether to keep the drop-down visible.
2803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @hide Only used by AutoCompleteTextView under special conditions.
2813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
2823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) {
2833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mDropDownAlwaysVisible = dropDownAlwaysVisible;
2843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
2853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
2863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
2873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return Whether the drop-down is visible under special conditions.
2883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @hide Only used by AutoCompleteTextView under special conditions.
2893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
2903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public boolean isDropDownAlwaysVisible() {
2913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mDropDownAlwaysVisible;
2923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
2933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
2943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
2953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Sets the operating mode for the soft input area.
2963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
29720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param mode The desired mode, see {@link android.view.WindowManager.LayoutParams#softInputMode}
29820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *             for the full list
2993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see android.view.WindowManager.LayoutParams#softInputMode
3003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #getSoftInputMode()
3013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
3023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setSoftInputMode(int mode) {
3033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mPopup.setSoftInputMode(mode);
3043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
3053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
3063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
3073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Returns the current value in {@link #setSoftInputMode(int)}.
3083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
3093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #setSoftInputMode(int)
3103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see android.view.WindowManager.LayoutParams#softInputMode
3113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
3123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public int getSoftInputMode() {
3133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mPopup.getSoftInputMode();
3143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
3153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
3163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
3173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Sets a drawable to use as the list item selector.
3183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
3193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param selector List selector drawable to use in the popup.
3203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
3213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setListSelector(Drawable selector) {
3223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mDropDownListHighlight = selector;
3233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
3243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
3253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
3263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return The background drawable for the popup window.
3273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
3283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public Drawable getBackground() {
3293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mPopup.getBackground();
3303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
3313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
3323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
3333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Sets a drawable to be the background for the popup window.
3343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
3353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param d A drawable to set as the background.
3363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
3373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setBackgroundDrawable(Drawable d) {
3383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mPopup.setBackgroundDrawable(d);
3393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
3403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
3413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
3423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Set an animation style to use when the popup window is shown or dismissed.
3433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
3443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param animationStyle Animation style to use.
3453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
3463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setAnimationStyle(int animationStyle) {
3473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mPopup.setAnimationStyle(animationStyle);
3483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
3493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
3503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
35120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Returns the animation style that will be used when the popup window is shown or dismissed.
3523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
3533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return Animation style that will be used.
3543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
3553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public int getAnimationStyle() {
3563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mPopup.getAnimationStyle();
3573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
3583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
3593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
3603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Returns the view that will be used to anchor this popup.
3613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
3623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return The popup's anchor view
3633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
3643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public View getAnchorView() {
3653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mDropDownAnchorView;
3663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
3673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
3683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
36920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Sets the popup's anchor view. This popup will always be positioned relative to the anchor
37020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * view when shown.
3713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
3723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param anchor The view to use as an anchor.
3733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
3743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setAnchorView(View anchor) {
3753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mDropDownAnchorView = anchor;
3763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
3773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
3783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
3793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return The horizontal offset of the popup from its anchor in pixels.
3803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
3813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public int getHorizontalOffset() {
3823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mDropDownHorizontalOffset;
3833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
3843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
3853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
3863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Set the horizontal offset of this popup from its anchor view in pixels.
3873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
3883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param offset The horizontal offset of the popup from its anchor.
3893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
3903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setHorizontalOffset(int offset) {
3913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mDropDownHorizontalOffset = offset;
3923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
3933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
3943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
3953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return The vertical offset of the popup from its anchor in pixels.
3963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
3973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public int getVerticalOffset() {
3983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (!mDropDownVerticalOffsetSet) {
3993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return 0;
4003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
4013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mDropDownVerticalOffset;
4023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
4033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
4043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
4053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Set the vertical offset of this popup from its anchor view in pixels.
4063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
4073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param offset The vertical offset of the popup from its anchor.
4083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
4093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setVerticalOffset(int offset) {
4103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mDropDownVerticalOffset = offset;
4113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mDropDownVerticalOffsetSet = true;
4123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
4133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
4143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
4153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return The width of the popup window in pixels.
4163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
4173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public int getWidth() {
4183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mDropDownWidth;
4193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
4203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
4213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
42220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Sets the width of the popup window in pixels. Can also be {@link #FILL_PARENT} or {@link
42320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * #WRAP_CONTENT}.
4243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
4253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param width Width of the popup window.
4263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
4273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setWidth(int width) {
4283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mDropDownWidth = width;
4293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
4303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
4313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
43220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Sets the width of the popup window by the size of its content. The final width may be larger
43320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * to accommodate styled window dressing.
4343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
4353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param width Desired width of content in pixels.
4363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
4373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setContentWidth(int width) {
4383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        Drawable popupBackground = mPopup.getBackground();
4393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (popupBackground != null) {
4403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            popupBackground.getPadding(mTempRect);
4413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mDropDownWidth = mTempRect.left + mTempRect.right + width;
4423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        } else {
4433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            setWidth(width);
4443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
4453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
4463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
4473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
4483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return The height of the popup window in pixels.
4493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
4503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public int getHeight() {
4513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mDropDownHeight;
4523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
4533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
4543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
4553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Sets the height of the popup window in pixels. Can also be {@link #FILL_PARENT}.
4563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
4573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param height Height of the popup window.
4583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
4593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setHeight(int height) {
4603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mDropDownHeight = height;
4613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
4623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
4633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
4643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Sets a listener to receive events when a list item is clicked.
4653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
4663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param clickListener Listener to register
4673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see ListView#setOnItemClickListener(android.widget.AdapterView.OnItemClickListener)
4683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
4693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setOnItemClickListener(AdapterView.OnItemClickListener clickListener) {
4703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mItemClickListener = clickListener;
4713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
4723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
4733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
4743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Sets a listener to receive events when a list item is selected.
4753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
4763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param selectedListener Listener to register.
4773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see ListView#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener)
4783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
4793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener selectedListener) {
4803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mItemSelectedListener = selectedListener;
4813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
4823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
4833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
4843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Set a view to act as a user prompt for this popup window. Where the prompt view will appear
4853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * is controlled by {@link #setPromptPosition(int)}.
4863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
4873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param prompt View to use as an informational prompt.
4883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
4893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setPromptView(View prompt) {
4903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        boolean showing = isShowing();
4913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (showing) {
4923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            removePromptView();
4933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
4943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mPromptView = prompt;
4953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (showing) {
4963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            show();
4973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
4983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
4993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
5013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Post a {@link #show()} call to the UI thread.
5023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
5033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void postShow() {
5043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mHandler.post(mShowDropDownRunnable);
5053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
5063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
50820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Show the popup list. If the list is already showing, this method will recalculate the popup's
50920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * size and position.
5103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
5113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void show() {
5123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        int height = buildDropDown();
5133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        int widthSpec = 0;
5153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        int heightSpec = 0;
5163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        boolean noInputMethod = isInputMethodNotNeeded();
5183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        // TODO(anirudhd) : Test and replicate this behaviour
5193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        // mPopup.setAllowScrollingAnchorParent(!noInputMethod);
5203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (mPopup.isShowing()) {
5223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) {
5233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                // The call to PopupWindow's update method below can accept -1 for any
5243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                // value you do not want to update.
5253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                widthSpec = -1;
5263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            } else if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) {
5273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                widthSpec = getAnchorView().getWidth();
5283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            } else {
5293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                widthSpec = mDropDownWidth;
5303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
5313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (mDropDownHeight == ViewGroup.LayoutParams.FILL_PARENT) {
5333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                // The call to PopupWindow's update method below can accept -1 for any
5343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                // value you do not want to update.
5353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.FILL_PARENT;
5363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                if (noInputMethod) {
5373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mPopup.setWindowLayoutMode(
5383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                            mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT ?
5393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                                    ViewGroup.LayoutParams.FILL_PARENT : 0, 0);
5403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                } else {
5413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mPopup.setWindowLayoutMode(
5423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                            mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT ?
5433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                                    ViewGroup.LayoutParams.FILL_PARENT : 0,
5443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                            ViewGroup.LayoutParams.FILL_PARENT);
5453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
5463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) {
5473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                heightSpec = height;
5483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            } else {
5493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                heightSpec = mDropDownHeight;
5503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
5513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible);
5533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mPopup.update(getAnchorView(), mDropDownHorizontalOffset,
5553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mDropDownVerticalOffset, widthSpec, heightSpec);
5563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        } else {
5573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) {
5583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                widthSpec = ViewGroup.LayoutParams.FILL_PARENT;
5593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            } else {
5603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) {
5613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mPopup.setWidth(getAnchorView().getWidth());
5623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                } else {
5633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mPopup.setWidth(mDropDownWidth);
5643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
5653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
5663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (mDropDownHeight == ViewGroup.LayoutParams.FILL_PARENT) {
5683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                heightSpec = ViewGroup.LayoutParams.FILL_PARENT;
5693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            } else {
5703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) {
5713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mPopup.setHeight(height);
5723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                } else {
5733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mPopup.setHeight(mDropDownHeight);
5743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
5753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
5763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mPopup.setWindowLayoutMode(widthSpec, heightSpec);
5783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            setClipToScreenEnabled(mPopup, true);
5793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // use outside touchable to dismiss drop down when touching outside of it, so
5813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // only set this if the dropdown is not always visible
5823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible);
5833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mPopup.setTouchInterceptor(mTouchInterceptor);
5843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mPopup.showAsDropDown(getAnchorView(),
5853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mDropDownHorizontalOffset, mDropDownVerticalOffset);
5863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mDropDownList.setSelection(ListView.INVALID_POSITION);
5873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (!mModal || mDropDownList.isInTouchMode()) {
5893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                clearListSelection();
5903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
5913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (!mModal) {
5923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                mHandler.post(mHideSelector);
5933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
5943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
5953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
5963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
5973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public static void setClipToScreenEnabled(PopupWindow mPopup, boolean enabled) {
5983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        try {
5993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            Field f = mPopup.getClass().getDeclaredField("mClipToScreen");
6003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            f.setAccessible(true);
6013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            f.setBoolean(mPopup, enabled);
6023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        } catch (NoSuchFieldException e) {
60379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            // No field
6043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        } catch (IllegalAccessException e) {
6053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            e.printStackTrace();
6063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
6073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mPopup.setClippingEnabled(!enabled);
6083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
6093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
6103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
6113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Dismiss the popup window.
6123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
6133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void dismiss() {
6143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mPopup.dismiss();
6153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        removePromptView();
6163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mPopup.setContentView(null);
6173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mDropDownList = null;
6183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mHandler.removeCallbacks(mResizePopupRunnable);
6193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
6203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
6213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
6223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Set a listener to receive a callback when the popup is dismissed.
6233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
6243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param listener Listener that will be notified when the popup is dismissed.
6253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
6263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
6273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mPopup.setOnDismissListener(listener);
6283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
6293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
6303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private void removePromptView() {
6313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (mPromptView != null) {
6323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            final ViewParent parent = mPromptView.getParent();
6333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (parent instanceof ViewGroup) {
6343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                final ViewGroup group = (ViewGroup) parent;
6353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                group.removeView(mPromptView);
6363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
6373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
6383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
6393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
6403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
64120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Control how the popup operates with an input method: one of {@link
64220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED}, or {@link
64320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * #INPUT_METHOD_NOT_NEEDED}.
6443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
64520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * <p>If the popup is showing, calling this method will take effect only the next time the popup
64620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * is shown or through a manual call to the {@link #show()} method.</p>
6473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
6483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #getInputMethodMode()
6493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #show()
6503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
6513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setInputMethodMode(int mode) {
6523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mPopup.setInputMethodMode(mode);
6533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
6543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
6553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
6563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Return the current value in {@link #setInputMethodMode(int)}.
6573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
6583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #setInputMethodMode(int)
6593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
6603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public int getInputMethodMode() {
6613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mPopup.getInputMethodMode();
6623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
6633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
6643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
66520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Set the selected position of the list. Only valid when {@link #isShowing()} == {@code true}.
6663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
6673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param position List position to set as selected.
6683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
6693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setSelection(int position) {
6703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        DropDownListView list = mDropDownList;
6713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (isShowing() && list != null) {
6723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            list.mListSelectionHidden = false;
6733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            list.setSelection(position);
6743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (list.getChoiceMode() != ListView.CHOICE_MODE_NONE) {
6753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                list.setItemChecked(position, true);
6763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
6773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
6783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
6793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
6803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
68120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Clear any current list selection. Only valid when {@link #isShowing()} == {@code true}.
6823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
6833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void clearListSelection() {
6843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        final DropDownListView list = mDropDownList;
6853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (list != null) {
6863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // WARNING: Please read the comment where mListSelectionHidden is declared
6873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            list.mListSelectionHidden = true;
6883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            //list.hideSelector();
6893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            list.requestLayout();
6903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
6913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
6923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
6933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
6943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return {@code true} if the popup is currently showing, {@code false} otherwise.
6953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
6963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public boolean isShowing() {
6973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mPopup.isShowing();
6983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
6993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
7003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
70120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return {@code true} if this popup is configured to assume the user does not need to interact
70220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *         with the IME while it is showing, {@code false} otherwise.
7033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
7043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public boolean isInputMethodNotNeeded() {
7053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mPopup.getInputMethodMode() == INPUT_METHOD_NOT_NEEDED;
7063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
7073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
7083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
7093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Perform an item click operation on the specified list adapter position.
7103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
7113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param position Adapter position for performing the click
71220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return true if the click action could be performed, false if not. (e.g. if the popup was not
71320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *         showing, this method would return false.)
7143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
7153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public boolean performItemClick(int position) {
7163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (isShowing()) {
7173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (mItemClickListener != null) {
7183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                final DropDownListView list = mDropDownList;
7193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                final View child = list.getChildAt(position - list.getFirstVisiblePosition());
7203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                final ListAdapter adapter = list.getAdapter();
7213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                mItemClickListener.onItemClick(list, child, position, adapter.getItemId(position));
7223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
7233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return true;
7243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
7253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return false;
7263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
7273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
7283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
7293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return The currently selected item or null if the popup is not showing.
7303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
7313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public Object getSelectedItem() {
7323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (!isShowing()) {
7333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return null;
7343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
7353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mDropDownList.getSelectedItem();
7363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
7373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
7383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
73920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return The position of the currently selected item or {@link ListView#INVALID_POSITION} if
74020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *         {@link #isShowing()} == {@code false}.
7413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see ListView#getSelectedItemPosition()
7423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
7433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public int getSelectedItemPosition() {
7443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (!isShowing()) {
7453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return ListView.INVALID_POSITION;
7463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
7473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mDropDownList.getSelectedItemPosition();
7483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
7493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
7503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
75120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return The ID of the currently selected item or {@link ListView#INVALID_ROW_ID} if {@link
75220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *         #isShowing()} == {@code false}.
7533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see ListView#getSelectedItemId()
7543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
7553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public long getSelectedItemId() {
7563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (!isShowing()) {
7573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return ListView.INVALID_ROW_ID;
7583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
7593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mDropDownList.getSelectedItemId();
7603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
7613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
7623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
76320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return The View for the currently selected item or null if {@link #isShowing()} == {@code
76420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *         false}.
7653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see ListView#getSelectedView()
7663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
7673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public View getSelectedView() {
7683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (!isShowing()) {
7693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return null;
7703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
7713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mDropDownList.getSelectedView();
7723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
7733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
7743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
77520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return The {@link ListView} displayed within the popup window. Only valid when {@link
77620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *         #isShowing()} == {@code true}.
7773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
7783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public ListView getListView() {
7793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return mDropDownList;
7803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
7813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
7823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
78320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * The maximum number of list items that can be visible and still have the list expand when
78420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * touched.
7853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
7863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param max Max number of items that can be visible and still allow the list to expand.
7873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
7883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    void setListItemExpandMax(int max) {
7893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mListItemExpandMaximum = max;
7903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
7913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
7923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
79320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Filter key down events. By forwarding key down events to this function, views using non-modal
79420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * ListPopupWindow can have it handle key selection of items.
7953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
7963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param keyCode keyCode param passed to the host view's onKeyDown
79720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param event   event param passed to the host view's onKeyDown
7983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return true if the event was handled, false if it was ignored.
7993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #setModal(boolean)
8003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
8013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public boolean onKeyDown(int keyCode, KeyEvent event) {
8023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        // when the drop down is shown, we drive it directly
8033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (isShowing()) {
8043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // the key events are forwarded to the list in the drop down view
8053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // note that ListView handles space but we don't want that to happen
8063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // also if selection is not currently in the drop down, then don't
8073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // let center or enter presses go there since that would cause it
8083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // to select one of its items
8093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (keyCode != KeyEvent.KEYCODE_SPACE
8103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    && (mDropDownList.getSelectedItemPosition() >= 0
8113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    || (keyCode != KeyEvent.KEYCODE_ENTER
8123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    && keyCode != KeyEvent.KEYCODE_DPAD_CENTER))) {
8133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                int curIndex = mDropDownList.getSelectedItemPosition();
8143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                boolean consumed;
8153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
8163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                final boolean below = !mPopup.isAboveAnchor();
8173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
8183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                final ListAdapter adapter = mAdapter;
8193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
8203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                boolean allEnabled;
8213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                int firstItem = Integer.MAX_VALUE;
8223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                int lastItem = Integer.MIN_VALUE;
8233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
8243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                if (adapter != null) {
8253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    allEnabled = adapter.areAllItemsEnabled();
8263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    firstItem = allEnabled ? 0 :
827ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                            mDropDownList.lookForSelectablePosition(0, true);
8283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    lastItem = allEnabled ? adapter.getCount() - 1 :
829ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                            mDropDownList.lookForSelectablePosition(adapter.getCount() - 1, false);
8303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
8313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
8323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                if ((below && keyCode == KeyEvent.KEYCODE_DPAD_UP && curIndex <= firstItem) ||
8333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        (!below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN && curIndex >= lastItem)) {
8343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // When the selection is at the top, we block the key
8353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // event to prevent focus from moving.
8363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    clearListSelection();
8373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
8383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    show();
8393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    return true;
8403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                } else {
8413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // WARNING: Please read the comment where mListSelectionHidden
8423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    //          is declared
8433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mDropDownList.mListSelectionHidden = false;
8443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
8453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
8463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                consumed = mDropDownList.onKeyDown(keyCode, event);
84720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                if (DEBUG) {
84820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    Log.v(TAG, "Key down: code=" + keyCode + " list consumed=" + consumed);
84920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                }
8503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
8513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                if (consumed) {
8523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // If it handled the key event, then the user is
8533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // navigating in the list, so we should put it in front.
8543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
8553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // Here's a little trick we need to do to make sure that
8563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // the list view is actually showing its focus indicator,
8573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // by ensuring it has focus and getting its window out
8583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // of touch mode.
8593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mDropDownList.requestFocusFromTouch();
8603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    show();
8613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
8623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    switch (keyCode) {
8633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        // avoid passing the focus from the text view to the
8643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        // next component
8653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        case KeyEvent.KEYCODE_ENTER:
8663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        case KeyEvent.KEYCODE_DPAD_CENTER:
8673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        case KeyEvent.KEYCODE_DPAD_DOWN:
8683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        case KeyEvent.KEYCODE_DPAD_UP:
8693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                            return true;
8703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    }
8713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                } else {
8723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    if (below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
8733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        // when the selection is at the bottom, we block the
8743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        // event to avoid going to the next focusable widget
8753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        if (curIndex == lastItem) {
8763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                            return true;
8773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        }
8783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    } else if (!below && keyCode == KeyEvent.KEYCODE_DPAD_UP &&
8793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                            curIndex == firstItem) {
8803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        return true;
8813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    }
8823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
8833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
8843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
8853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
8863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return false;
8873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
8883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
8893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
89020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Filter key down events. By forwarding key up events to this function, views using non-modal
89120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * ListPopupWindow can have it handle key selection of items.
8923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
8933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param keyCode keyCode param passed to the host view's onKeyUp
89420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param event   event param passed to the host view's onKeyUp
8953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return true if the event was handled, false if it was ignored.
8963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #setModal(boolean)
8973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
8983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public boolean onKeyUp(int keyCode, KeyEvent event) {
8993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (isShowing() && mDropDownList.getSelectedItemPosition() >= 0) {
9003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            boolean consumed = mDropDownList.onKeyUp(keyCode, event);
9013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (consumed) {
9023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                switch (keyCode) {
9033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // if the list accepts the key events and the key event
9043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // was a click, the text view gets the selected item
9053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // from the drop down as its content
9063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    case KeyEvent.KEYCODE_ENTER:
9073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    case KeyEvent.KEYCODE_DPAD_CENTER:
9083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        dismiss();
9093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        break;
9103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
9113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
9123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return consumed;
9133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
9143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return false;
9153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
9163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
9173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
91820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Filter pre-IME key events. By forwarding {@link View#onKeyPreIme(int, KeyEvent)} events to
91920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * this function, views using ListPopupWindow can have it dismiss the popup when the back key is
92020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * pressed.
9213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
9223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @param keyCode keyCode param passed to the host view's onKeyPreIme
92320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param event   event param passed to the host view's onKeyPreIme
9243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return true if the event was handled, false if it was ignored.
9253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @see #setModal(boolean)
9263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
9273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
9283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (keyCode == KeyEvent.KEYCODE_BACK && isShowing()) {
9293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // special case for the back key, we do not even try to send it
9303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // to the drop down list but instead, consume it immediately
9313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            //TODO(anirudhd): No dispatcher APIs in eclair
9323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
9333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return false;
9343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
9353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
9363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
93720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * <p>Builds the popup window's content and returns the height the popup should have. Returns -1
93820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * when the content already exists.</p>
9393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
9403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @return the content's height or -1 if content already exists
9413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
9423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private int buildDropDown() {
9433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        ViewGroup dropDownView;
9443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        int otherHeights = 0;
9453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
9463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (mDropDownList == null) {
9473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            Context context = mContext;
9483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
9493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            /**
9503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani             * This Runnable exists for the sole purpose of checking if the view layout has got
9513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani             * completed and if so call showDropDown to display the drop down. This is used to show
9523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani             * the drop down as soon as possible after user opens up the search dialog, without
9533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani             * waiting for the normal UI pipeline to do it's job which is slower than this method.
9543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani             */
9553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mShowDropDownRunnable = new Runnable() {
9563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                public void run() {
9573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    // View layout should be all done before displaying the drop down.
9583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    View view = getAnchorView();
9593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    if (view != null && view.getWindowToken() != null) {
9603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        show();
9613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    }
9623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
9633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            };
9643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
9653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mDropDownList = new DropDownListView(context, !mModal);
9663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (mDropDownListHighlight != null) {
9673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                mDropDownList.setSelector(mDropDownListHighlight);
9683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
9693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mDropDownList.setAdapter(mAdapter);
9703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mDropDownList.setOnItemClickListener(mItemClickListener);
9713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mDropDownList.setFocusable(true);
9723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mDropDownList.setFocusableInTouchMode(true);
9733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mDropDownList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
9743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                public void onItemSelected(AdapterView<?> parent, View view,
97520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        int position, long id) {
9763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
9773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    if (position != -1) {
9783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        DropDownListView dropDownList = mDropDownList;
9793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
9803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        if (dropDownList != null) {
9813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                            dropDownList.mListSelectionHidden = false;
9823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        }
9833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    }
9843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
9853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
9863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                public void onNothingSelected(AdapterView<?> parent) {
9873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
9883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            });
9893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mDropDownList.setOnScrollListener(mScrollListener);
9903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
9913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (mItemSelectedListener != null) {
9923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                mDropDownList.setOnItemSelectedListener(mItemSelectedListener);
9933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
9943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
9953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            dropDownView = mDropDownList;
9963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
9973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            View hintView = mPromptView;
9983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (hintView != null) {
9993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                // if a hint has been specified, we accomodate more space for it and
10003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                // add a text view in the drop down menu, at the bottom of the list
10013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                LinearLayout hintContainer = new LinearLayout(context);
10023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                hintContainer.setOrientation(LinearLayout.VERTICAL);
10033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                LinearLayout.LayoutParams hintParams = new LinearLayout.LayoutParams(
10053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        ViewGroup.LayoutParams.FILL_PARENT, 0, 1.0f
10063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                );
10073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                switch (mPromptPosition) {
10093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    case POSITION_PROMPT_BELOW:
10103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        hintContainer.addView(dropDownView, hintParams);
10113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        hintContainer.addView(hintView);
10123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        break;
10133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    case POSITION_PROMPT_ABOVE:
10153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        hintContainer.addView(hintView);
10163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        hintContainer.addView(dropDownView, hintParams);
10173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        break;
10183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    default:
10203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        Log.e(TAG, "Invalid hint position " + mPromptPosition);
10213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        break;
10223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
10233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                // measure the hint's height to find how much more vertical space
10253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                // we need to add to the drop down's height
10263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                int widthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.AT_MOST);
10273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                int heightSpec = MeasureSpec.UNSPECIFIED;
10283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                hintView.measure(widthSpec, heightSpec);
10293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams();
10313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                otherHeights = hintView.getMeasuredHeight() + hintParams.topMargin
10323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        + hintParams.bottomMargin;
10333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                dropDownView = hintContainer;
10353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
10363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mPopup.setContentView(dropDownView);
10383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        } else {
10393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            dropDownView = (ViewGroup) mPopup.getContentView();
10403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            final View view = mPromptView;
10413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (view != null) {
10423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                LinearLayout.LayoutParams hintParams =
10433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        (LinearLayout.LayoutParams) view.getLayoutParams();
10443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                otherHeights = view.getMeasuredHeight() + hintParams.topMargin
10453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        + hintParams.bottomMargin;
10463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
10473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
10483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        // getMaxAvailableHeight() subtracts the padding, so we put it back
10503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        // to get the available height for the whole window
10513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        int padding = 0;
10523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        Drawable background = mPopup.getBackground();
10533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (background != null) {
10543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            background.getPadding(mTempRect);
10553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            padding = mTempRect.top + mTempRect.bottom;
10563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // If we don't have an explicit vertical offset, determine one from the window
10583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // background so that content will line up.
10593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (!mDropDownVerticalOffsetSet) {
10603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                mDropDownVerticalOffset = -mTempRect.top;
10613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
10623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        } else {
10633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mTempRect.setEmpty();
10643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
10653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        // Max height available on the screen for a popup.
10673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        boolean ignoreBottomDecorations =
10683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED;
10693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        final int maxHeight = getMaxAvailableHeight(
1070ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                getAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations);
10713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (mDropDownAlwaysVisible || mDropDownHeight == ViewGroup.LayoutParams.FILL_PARENT) {
10733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return maxHeight + padding;
10743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
10753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
10763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        final int childWidthSpec;
10773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        switch (mDropDownWidth) {
10783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            case ViewGroup.LayoutParams.WRAP_CONTENT:
10793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                childWidthSpec = MeasureSpec.makeMeasureSpec(
10803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        mContext.getResources().getDisplayMetrics().widthPixels -
10813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                                (mTempRect.left + mTempRect.right),
10823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        MeasureSpec.AT_MOST);
10833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                break;
10843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            case ViewGroup.LayoutParams.FILL_PARENT:
10853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                childWidthSpec = MeasureSpec.makeMeasureSpec(
10863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        mContext.getResources().getDisplayMetrics().widthPixels -
10873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                                (mTempRect.left + mTempRect.right),
10883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        MeasureSpec.EXACTLY);
10893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                break;
10903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            default:
10913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                childWidthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.EXACTLY);
10923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                break;
10933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
1094ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns
109579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        final int listContent = mDropDownList.measureHeightOfChildrenCompat(childWidthSpec,
10963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                0, DropDownListView.NO_POSITION, maxHeight - otherHeights, -1);
10973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        // add padding only if the list has items in it, that way we don't show
10983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        // the popup if it is not needed
109920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (listContent > 0) {
110020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            otherHeights += padding;
110120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
11023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
11033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return listContent + otherHeights;
11043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
11053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
11063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
11073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * Copied from PopupWindow.java of JB
11083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
110920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Returns the maximum height that is available for the popup to be completely shown, optionally
111020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * ignoring any bottom decorations such as the input method. It is recommended that this height
111120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * be the maximum for the popup's height, otherwise it is possible that the popup will be
11123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * clipped.
11133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
111420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param anchor                  The view on which the popup window must be anchored.
111520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param yOffset                 y offset from the view's bottom edge
111620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param ignoreBottomDecorations if true, the height returned will be all the way to the bottom
111720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *                                of the display, ignoring any bottom decorations
111820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return The maximum available height for the popup to be completely shown.
11193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     * @hide Pending API council approval.
11203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
11213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) {
11223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        final Rect displayFrame = new Rect();
11233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        anchor.getWindowVisibleDisplayFrame(displayFrame);
11243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
11253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        int[] mDrawingLocation = new int[2];
11263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        final int[] anchorPos = mDrawingLocation;
11273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        anchor.getLocationOnScreen(anchorPos);
11283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
11293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        int bottomEdge = displayFrame.bottom;
11303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (ignoreBottomDecorations) {
11313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            Resources res = anchor.getContext().getResources();
11323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            bottomEdge = res.getDisplayMetrics().heightPixels;
11333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
11343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
11353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
11363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
11373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        // anchorPos[1] is distance from anchor to top of screen
11383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        int returnedHeight = Math.max(distanceToBottom, distanceToTop);
11393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (mPopup.getBackground() != null) {
11403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mPopup.getBackground().getPadding(mTempRect);
11413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            returnedHeight -= mTempRect.top + mTempRect.bottom;
11423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
11433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
11443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        return returnedHeight;
11453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
11463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
11473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
114820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Set the layout direction for this popup. Should be a resolved direction as the popup as no
114920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * capacity to do the resolution on his own.
11503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     *
115120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param layoutDirection One of {@link View#LAYOUT_DIRECTION_LTR}, {@link
115220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *                        View#LAYOUT_DIRECTION_RTL},
11533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
11543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    public void setLayoutDirection(int layoutDirection) {
11553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        mLayoutDirection = layoutDirection;
11563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        if (mDropDownList != null) {
11573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // BiDi support
11583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // mDropDownList.setLayoutDirection(mLayoutDirection);
11593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
11603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
11613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
11623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    /**
116320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * <p>Wrapper class for a ListView. This wrapper can hijack the focus to make sure the list uses
116420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * the appropriate drawables and states when displayed on screen within a drop down. The focus
116520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * is never actually passed to the drop down in this mode; the list only looks focused.</p>
11663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani     */
11673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private static class DropDownListView extends ListView {
116820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
11693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        private static final String TAG = ListPopupWindow.TAG + ".DropDownListView";
117020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
11713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        /*
117220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * WARNING: This is a workaround for a touch mode issue.
117320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        *
117420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * Touch mode is propagated lazily to windows. This causes problems in
117520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * the following scenario:
117620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * - Type something in the AutoCompleteTextView and get some results
117720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * - Move down with the d-pad to select an item in the list
117820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * - Move up with the d-pad until the selection disappears
117920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * - Type more text in the AutoCompleteTextView *using the soft keyboard*
118020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        *   and get new results; you are now in touch mode
118120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * - The selection comes back on the first item in the list, even though
118220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        *   the list is supposed to be in touch mode
118320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        *
118420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * Using the soft keyboard triggers the touch mode change but that change
118520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * is propagated to our window only after the first list layout, therefore
118620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * after the list attempts to resurrect the selection.
118720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        *
118820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * The trick to work around this issue is to pretend the list is in touch
118920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * mode when we know that the selection should not appear, that is when
119020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * we know the user moved the selection away from the list.
119120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        *
119220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * This boolean is set to true whenever we explicitly hide the list's
119320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * selection and reset to false whenever we know the user moved the
119420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * selection back to the list.
119520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        *
119620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * When this boolean is true, isInTouchMode() returns true, otherwise it
119720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        * returns super.isInTouchMode().
119820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        */
11993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        private boolean mListSelectionHidden;
12003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
12013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
12023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public static final int INVALID_POSITION = -1;
120320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
12043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        static final int NO_POSITION = -1;
12053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
12063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
12073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        /**
12083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * True if this wrapper should fake focus.
12093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         */
12103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        private boolean mHijackFocus;
12113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
12123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        /**
12133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * <p>Creates a new list view wrapper.</p>
12143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         *
12153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * @param context this view's context
12163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         */
12173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public DropDownListView(Context context, boolean hijackFocus) {
12183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            super(context, null, R.attr.dropDownListViewStyle);
12193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            mHijackFocus = hijackFocus;
12203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // TODO: Add an API to control this
12213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            setCacheColorHint(0); // Transparent, since the background drawable could be anything.
12223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
12233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
12243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        /**
12253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * Find a position that can be selected (i.e., is not a separator).
12263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         *
12273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * @param position The starting position to look at.
12283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * @param lookDown Whether to look down for other positions.
12293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * @return The next selectable position starting at position and then searching either up or
12303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         *         down. Returns {@link #INVALID_POSITION} if nothing can be found.
12313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         */
12323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        int lookForSelectablePosition(int position, boolean lookDown) {
12333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            final ListAdapter adapter = getAdapter();
12343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (adapter == null || isInTouchMode()) {
12353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                return INVALID_POSITION;
12363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
12373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
12383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            final int count = adapter.getCount();
12393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (!getAdapter().areAllItemsEnabled()) {
12403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                if (lookDown) {
12413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    position = Math.max(0, position);
12423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    while (position < count && !adapter.isEnabled(position)) {
12433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        position++;
12443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    }
12453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                } else {
12463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    position = Math.min(position, count - 1);
12473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    while (position >= 0 && !adapter.isEnabled(position)) {
12483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                        position--;
12493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    }
12503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
12513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
12523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                if (position < 0 || position >= count) {
12533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    return INVALID_POSITION;
12543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
12553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                return position;
12563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            } else {
12573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                if (position < 0 || position >= count) {
12583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    return INVALID_POSITION;
12593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                }
12603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                return position;
12613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
12623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
12633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
12643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        @Override
12653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public boolean isInTouchMode() {
12663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // WARNING: Please read the comment where mListSelectionHidden is declared
12673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return (mHijackFocus && mListSelectionHidden) || super.isInTouchMode();
12683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
12693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
12703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        /**
12713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * <p>Returns the focus state in the drop down.</p>
12723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         *
12733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * @return true always if hijacking focus
12743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         */
12753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        @Override
12763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public boolean hasWindowFocus() {
12773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return mHijackFocus || super.hasWindowFocus();
12783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
12793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
12803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        /**
12813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * <p>Returns the focus state in the drop down.</p>
12823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         *
12833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * @return true always if hijacking focus
12843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         */
12853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        @Override
12863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public boolean isFocused() {
12873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return mHijackFocus || super.isFocused();
12883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
12893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
12903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        /**
12913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * <p>Returns the focus state in the drop down.</p>
12923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         *
12933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * @return true always if hijacking focus
12943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         */
12953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        @Override
12963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public boolean hasFocus() {
12973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return mHijackFocus || super.hasFocus();
12983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
12993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
13003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        /**
130120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         * Measures the height of the given range of children (inclusive) and returns the height
130220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         * with this ListView's padding and divider heights included. If maxHeight is provided, the
130320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         * measuring will stop when the current height reaches maxHeight.
13043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         *
130520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         * @param widthMeasureSpec             The width measure spec to be given to a child's
130620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     {@link View#measure(int, int)}.
130720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         * @param startPosition                The position of the first child to be shown.
130820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         * @param endPosition                  The (inclusive) position of the last child to be
130920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     shown. Specify {@link #NO_POSITION} if the last child
131020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     should be the last available child from the adapter.
131120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         * @param maxHeight                    The maximum height that will be returned (if all the
131220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     children don't fit in this value, this value will be
131320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     returned).
131420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         * @param disallowPartialChildPosition In general, whether the returned height should only
131520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     contain entire children. This is more powerful--it is
131620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     the first inclusive position at which partial
131720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     children will not be allowed. Example: it looks nice
131820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     to have at least 3 completely visible children, and
131920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     in portrait this will most likely fit; but in
132020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     landscape there could be times when even 2 children
132120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     can not be completely shown, so a value of 2
132220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     (remember, inclusive) would be good (assuming
132320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns         *                                     startPosition is 0).
13243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         * @return The height of this ListView with the given children.
13253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani         */
132679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        final int measureHeightOfChildrenCompat(int widthMeasureSpec, int startPosition,
132720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                int endPosition, final int maxHeight,
132820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                int disallowPartialChildPosition) {
1329ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns
1330ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            final int paddingTop = getListPaddingTop();
1331ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            final int paddingBottom = getListPaddingBottom();
1332ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            final int paddingLeft = getListPaddingLeft();
1333ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            final int paddingRight = getListPaddingRight();
1334ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            final int reportedDividerHeight = getDividerHeight();
1335ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            final Drawable divider = getDivider();
13363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
13373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            final ListAdapter adapter = getAdapter();
13383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
13393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (adapter == null) {
1340ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                return paddingTop + paddingBottom;
13413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
13423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
13433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            // Include the padding of the list
1344ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            int returnedHeight = paddingTop + paddingBottom;
134520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            final int dividerHeight = ((reportedDividerHeight > 0) && divider != null)
134620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    ? reportedDividerHeight : 0;
1347ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns
1348ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            // The previous height value that was less than maxHeight and contained
1349ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            // no partial children
1350ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            int prevHeightWithoutPartialChild = 0;
1351ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns
1352ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            View child = null;
1353ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            int viewType = 0;
1354ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            int count = adapter.getCount();
1355ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            for (int i = 0; i < count; i++) {
1356ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                int newType = adapter.getItemViewType(i);
1357ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                if (newType != viewType) {
1358ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                    child = null;
1359ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                    viewType = newType;
1360ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                }
136120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                child = adapter.getView(i, child, this);
136220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                ;
1363ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns
1364ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                // Compute child height spec
1365ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                int heightMeasureSpec;
1366ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                int childHeight = child.getLayoutParams().height;
1367ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                if (childHeight > 0) {
136820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    heightMeasureSpec = MeasureSpec
136920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                            .makeMeasureSpec(childHeight, MeasureSpec.EXACTLY);
1370ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                } else {
1371ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
1372ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                }
1373ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                child.measure(widthMeasureSpec, heightMeasureSpec);
1374ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns
1375ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                if (i > 0) {
1376ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                    // Count the divider for all but one child
1377ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                    returnedHeight += dividerHeight;
1378ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                }
1379ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns
1380ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                returnedHeight += child.getMeasuredHeight();
1381ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns
1382ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                if (returnedHeight >= maxHeight) {
138320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    // We went over, figure out which height to return.  If returnedHeight >
138420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    // maxHeight, then the i'th position did not fit completely.
1385ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                    return (disallowPartialChildPosition >= 0) // Disallowing is enabled (> -1)
1386ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                            && (i > disallowPartialChildPosition) // We've past the min pos
1387ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                            && (prevHeightWithoutPartialChild > 0) // We have a prev height
1388ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                            && (returnedHeight != maxHeight) // i'th child did not fit completely
1389ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                            ? prevHeightWithoutPartialChild
1390ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                            : maxHeight;
1391ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                }
1392ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns
1393ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                if ((disallowPartialChildPosition >= 0) && (i >= disallowPartialChildPosition)) {
1394ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                    prevHeightWithoutPartialChild = returnedHeight;
1395ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns                }
1396ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            }
1397ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns
1398ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            // At this point, we went through the range of children, and they each
1399ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns            // completely fit, so return the returnedHeight
14003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return returnedHeight;
14013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
14023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
14033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
14043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
14053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private class PopupDataSetObserver extends DataSetObserver {
140620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
14073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        @Override
14083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public void onChanged() {
14093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (isShowing()) {
14103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                // Resize the popup to fit new content
14113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                show();
14123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
14133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
14143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
14153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        @Override
14163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public void onInvalidated() {
14173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            dismiss();
14183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
14193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
14203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
14213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private class ListSelectorHider implements Runnable {
142220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
14233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public void run() {
14243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            clearListSelection();
14253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
14263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
14273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
14283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private class ResizePopupRunnable implements Runnable {
142920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
14303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public void run() {
14313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (mDropDownList != null && mDropDownList.getCount() > mDropDownList.getChildCount() &&
14323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mDropDownList.getChildCount() <= mListItemExpandMaximum) {
14333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
14343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                show();
14353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
14363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
14373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
14383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
14393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private class PopupTouchInterceptor implements OnTouchListener {
144020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
14413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public boolean onTouch(View v, MotionEvent event) {
14423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            final int action = event.getAction();
14433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            final int x = (int) event.getX();
14443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            final int y = (int) event.getY();
14453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
14463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (action == MotionEvent.ACTION_DOWN &&
14473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    mPopup != null && mPopup.isShowing() &&
14483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    (x >= 0 && x < mPopup.getWidth() && y >= 0 && y < mPopup.getHeight())) {
14493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                mHandler.postDelayed(mResizePopupRunnable, EXPAND_LIST_TIMEOUT);
14503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            } else if (action == MotionEvent.ACTION_UP) {
14513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                mHandler.removeCallbacks(mResizePopupRunnable);
14523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
14533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            return false;
14543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
14553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
14563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
14573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    private class PopupScrollListener implements ListView.OnScrollListener {
145820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
14593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
146020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                int totalItemCount) {
14613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
14623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
14633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani
14643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        public void onScrollStateChanged(AbsListView view, int scrollState) {
14653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            if (scrollState == SCROLL_STATE_TOUCH_SCROLL &&
14663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                    !isInputMethodNotNeeded() && mPopup.getContentView() != null) {
14673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                mHandler.removeCallbacks(mResizePopupRunnable);
14683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani                mResizePopupRunnable.run();
14693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani            }
14703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani        }
14713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani    }
14723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani}