1c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell/*
2c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Copyright (C) 2010 The Android Open Source Project
3c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell *
4c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * you may not use this file except in compliance with the License.
6c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * You may obtain a copy of the License at
7c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell *
8c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell *
10c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * Unless required by applicable law or agreed to in writing, software
11c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * See the License for the specific language governing permissions and
14c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * limitations under the License.
15c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */
16c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
17c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellpackage android.widget;
18c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
19c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.content.Context;
20c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.database.DataSetObserver;
21c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.graphics.Rect;
22c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.graphics.drawable.Drawable;
23c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.os.Handler;
24c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.util.AttributeSet;
25c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.util.Log;
26c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.KeyEvent;
27c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.MotionEvent;
28c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View;
29c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View.MeasureSpec;
30c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellimport android.view.View.OnTouchListener;
31711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunneimport android.view.ViewGroup;
32711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunneimport android.view.ViewParent;
33c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
34c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell/**
35c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * A ListPopupWindow anchors itself to a host view and displays a
3665d79fbe55c017edd9419ddb71939c8916471390Adam Powell * list of choices.
37c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell *
38c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * <p>ListPopupWindow contains a number of tricky behaviors surrounding
39c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * positioning, scrolling parents to fit the dropdown, interacting
40c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * sanely with the IME if present, and others.
41c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell *
42c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.widget.AutoCompleteTextView
43c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell * @see android.widget.Spinner
44c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell */
45c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powellpublic class ListPopupWindow {
46c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private static final String TAG = "ListPopupWindow";
47c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private static final boolean DEBUG = false;
48c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
49c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
50c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * This value controls the length of time that the user
51c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * must leave a pointer down without scrolling to expand
52c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * the autocomplete dropdown list to cover the IME.
53c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
54c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private static final int EXPAND_LIST_TIMEOUT = 250;
55c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
56c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private Context mContext;
57c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private PopupWindow mPopup;
58c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private ListAdapter mAdapter;
59c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private DropDownListView mDropDownList;
60c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
61c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private int mDropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT;
62c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private int mDropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT;
63c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private int mDropDownHorizontalOffset;
64c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private int mDropDownVerticalOffset;
658132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell    private boolean mDropDownVerticalOffsetSet;
66c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
67c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private boolean mDropDownAlwaysVisible = false;
68c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private boolean mForceIgnoreOutsideTouch = false;
69348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    int mListItemExpandMaximum = Integer.MAX_VALUE;
70c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
71c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private View mPromptView;
72c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private int mPromptPosition = POSITION_PROMPT_ABOVE;
73c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
74c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private DataSetObserver mObserver;
75c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
76c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private View mDropDownAnchorView;
77c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
78c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private Drawable mDropDownListHighlight;
79c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
80c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private AdapterView.OnItemClickListener mItemClickListener;
81c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private AdapterView.OnItemSelectedListener mItemSelectedListener;
82c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
834267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell    private final ResizePopupRunnable mResizePopupRunnable = new ResizePopupRunnable();
84c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private final PopupTouchInterceptor mTouchInterceptor = new PopupTouchInterceptor();
85c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private final PopupScrollListener mScrollListener = new PopupScrollListener();
86c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private final ListSelectorHider mHideSelector = new ListSelectorHider();
87c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private Runnable mShowDropDownRunnable;
88c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
89c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private Handler mHandler = new Handler();
90c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
91c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private Rect mTempRect = new Rect();
92c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
93c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private boolean mModal;
94c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
95c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
96c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * The provided prompt view should appear above list content.
97c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
98c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #setPromptPosition(int)
99c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #getPromptPosition()
100c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #setPromptView(View)
101c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
102c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public static final int POSITION_PROMPT_ABOVE = 0;
103c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
104c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
105c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * The provided prompt view should appear below list content.
106c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
107c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #setPromptPosition(int)
108c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #getPromptPosition()
109c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #setPromptView(View)
110c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
111c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public static final int POSITION_PROMPT_BELOW = 1;
112c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
113c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
114c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Alias for {@link ViewGroup.LayoutParams#MATCH_PARENT}.
115c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * If used to specify a popup width, the popup will match the width of the anchor view.
116c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * If used to specify a popup height, the popup will fill available space.
117c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
118c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public static final int MATCH_PARENT = ViewGroup.LayoutParams.MATCH_PARENT;
119c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
120c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
121c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Alias for {@link ViewGroup.LayoutParams#WRAP_CONTENT}.
122c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * If used to specify a popup width, the popup will use the width of its content.
123c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
124c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public static final int WRAP_CONTENT = ViewGroup.LayoutParams.WRAP_CONTENT;
125c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
126c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
127c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Mode for {@link #setInputMethodMode(int)}: the requirements for the
128c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * input method should be based on the focusability of the popup.  That is
129c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * if it is focusable than it needs to work with the input method, else
130c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * it doesn't.
131c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
132c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public static final int INPUT_METHOD_FROM_FOCUSABLE = PopupWindow.INPUT_METHOD_FROM_FOCUSABLE;
133c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
134c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
135c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Mode for {@link #setInputMethodMode(int)}: this popup always needs to
136c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * work with an input method, regardless of whether it is focusable.  This
137c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * means that it will always be displayed so that the user can also operate
138c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * the input method while it is shown.
139c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
140c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public static final int INPUT_METHOD_NEEDED = PopupWindow.INPUT_METHOD_NEEDED;
141c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
142c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
143c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Mode for {@link #setInputMethodMode(int)}: this popup never needs to
144c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * work with an input method, regardless of whether it is focusable.  This
145c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * means that it will always be displayed to use as much space on the
146c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * screen as needed, regardless of whether this covers the input method.
147c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
148c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public static final int INPUT_METHOD_NOT_NEEDED = PopupWindow.INPUT_METHOD_NOT_NEEDED;
149c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
150c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
151c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Create a new, empty popup window capable of displaying items from a ListAdapter.
152c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}.
153c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
154c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param context Context used for contained views.
155c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
156c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public ListPopupWindow(Context context) {
157c2238d006237ebf1296074d80fb4f4a2741ef880Daniel Lehmann        this(context, null, com.android.internal.R.attr.listPopupWindowStyle, 0);
158c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
159c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
160c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
161c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Create a new, empty popup window capable of displaying items from a ListAdapter.
162c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}.
163c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
164c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param context Context used for contained views.
165c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param attrs Attributes from inflating parent views used to style the popup.
166c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
167c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public ListPopupWindow(Context context, AttributeSet attrs) {
1680b2d306e7000f4c0c6ad4e00d494bb401d8a9fc2Adam Powell        this(context, attrs, com.android.internal.R.attr.listPopupWindowStyle, 0);
169c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
170c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
171c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
172c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Create a new, empty popup window capable of displaying items from a ListAdapter.
173c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}.
174c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
175c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param context Context used for contained views.
176c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param attrs Attributes from inflating parent views used to style the popup.
177c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param defStyleAttr Default style attribute to use for popup content.
178c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
179c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr) {
180c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        this(context, attrs, defStyleAttr, 0);
181c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
182c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
183c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
184c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Create a new, empty popup window capable of displaying items from a ListAdapter.
185c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Backgrounds should be set using {@link #setBackgroundDrawable(Drawable)}.
186c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
187c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param context Context used for contained views.
188c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param attrs Attributes from inflating parent views used to style the popup.
189c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param defStyleAttr Style attribute to read for default styling of popup content.
190c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param defStyleRes Style resource ID to use for default styling of popup content.
191c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
192c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
193c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mContext = context;
194c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup = new PopupWindow(context, attrs, defStyleAttr, defStyleRes);
1956f5e934b96c400f610b1c5ad228cc60cab5d443fAdam Powell        mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
196c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
197c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
198c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
199c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Sets the adapter that provides the data and the views to represent the data
200c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * in this popup window.
201c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
202c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param adapter The adapter to use to create this window's content.
203c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
204c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setAdapter(ListAdapter adapter) {
205c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (mObserver == null) {
206c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mObserver = new PopupDataSetObserver();
207c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        } else if (mAdapter != null) {
20899969da3772d9a0f5079672847ca4f2ad819c1bbAdam Powell            mAdapter.unregisterDataSetObserver(mObserver);
209c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
210c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mAdapter = adapter;
211c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (mAdapter != null) {
212c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            adapter.registerDataSetObserver(mObserver);
213c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
214c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
215c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (mDropDownList != null) {
216c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mDropDownList.setAdapter(mAdapter);
217c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
218c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
219c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
220c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
221c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Set where the optional prompt view should appear. The default is
222c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * {@link #POSITION_PROMPT_ABOVE}.
223c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
224c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param position A position constant declaring where the prompt should be displayed.
225c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
226c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #POSITION_PROMPT_ABOVE
227c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #POSITION_PROMPT_BELOW
228c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
229c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setPromptPosition(int position) {
230c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPromptPosition = position;
231c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
232c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
233c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
234c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return Where the optional prompt view should appear.
235c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
236c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #POSITION_PROMPT_ABOVE
237c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #POSITION_PROMPT_BELOW
238c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
239c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public int getPromptPosition() {
240c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPromptPosition;
241c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
242c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
243c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
244c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Set whether this window should be modal when shown.
245c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
246c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * <p>If a popup window is modal, it will receive all touch and key input.
247c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * If the user touches outside the popup window's content area the popup window
248c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * will be dismissed.
249c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
250c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param modal {@code true} if the popup window should be modal, {@code false} otherwise.
251c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
252c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setModal(boolean modal) {
253c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mModal = true;
254c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setFocusable(modal);
255c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
256c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
257c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
258c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Returns whether the popup window will be modal when shown.
259c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
260c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return {@code true} if the popup window will be modal, {@code false} otherwise.
261c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
262c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public boolean isModal() {
263c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mModal;
264c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
265c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
266c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
267c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Forces outside touches to be ignored. Normally if {@link #isDropDownAlwaysVisible()} is
268c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * false, we allow outside touch to dismiss the dropdown. If this is set to true, then we
269c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * ignore outside touch even when the drop down is not set to always visible.
270c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
271c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @hide Used only by AutoCompleteTextView to handle some internal special cases.
272c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
273c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setForceIgnoreOutsideTouch(boolean forceIgnoreOutsideTouch) {
274c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mForceIgnoreOutsideTouch = forceIgnoreOutsideTouch;
275c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
276c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
277c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
278c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Sets whether the drop-down should remain visible under certain conditions.
279c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
280c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * The drop-down will occupy the entire screen below {@link #getAnchorView} regardless
281c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * of the size or content of the list.  {@link #getBackground()} will fill any space
282c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * that is not used by the list.
283c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
284c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param dropDownAlwaysVisible Whether to keep the drop-down visible.
285c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
286c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @hide Only used by AutoCompleteTextView under special conditions.
287c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
288c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) {
289c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mDropDownAlwaysVisible = dropDownAlwaysVisible;
290c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
291c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
292c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
293c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return Whether the drop-down is visible under special conditions.
294c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
295c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @hide Only used by AutoCompleteTextView under special conditions.
296c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
297c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public boolean isDropDownAlwaysVisible() {
298c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mDropDownAlwaysVisible;
299c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
300c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
301c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
302c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Sets the operating mode for the soft input area.
303c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
304c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param mode The desired mode, see
305c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *        {@link android.view.WindowManager.LayoutParams#softInputMode}
306c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *        for the full list
307c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
308c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see android.view.WindowManager.LayoutParams#softInputMode
309c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #getSoftInputMode()
310c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
311c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setSoftInputMode(int mode) {
312c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setSoftInputMode(mode);
313c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
314c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
315c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
316c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Returns the current value in {@link #setSoftInputMode(int)}.
317c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
318c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #setSoftInputMode(int)
319c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see android.view.WindowManager.LayoutParams#softInputMode
320c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
321c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public int getSoftInputMode() {
322c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.getSoftInputMode();
323c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
324c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
325c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
326c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Sets a drawable to use as the list item selector.
327c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
328c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param selector List selector drawable to use in the popup.
329c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
330c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setListSelector(Drawable selector) {
331c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mDropDownListHighlight = selector;
332c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
333c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
334c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
335c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return The background drawable for the popup window.
336c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
337c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public Drawable getBackground() {
338c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.getBackground();
339c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
340c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
341c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
342c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Sets a drawable to be the background for the popup window.
343c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
344c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param d A drawable to set as the background.
345c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
346c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setBackgroundDrawable(Drawable d) {
347c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setBackgroundDrawable(d);
348c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
349c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
350c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
351c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Set an animation style to use when the popup window is shown or dismissed.
352c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
353c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param animationStyle Animation style to use.
354c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
355c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setAnimationStyle(int animationStyle) {
356c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setAnimationStyle(animationStyle);
357c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
358c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
359c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
360c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Returns the animation style that will be used when the popup window is
361c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * shown or dismissed.
362c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
363c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return Animation style that will be used.
364c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
365c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public int getAnimationStyle() {
366c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.getAnimationStyle();
367c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
368c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
369c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
370c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Returns the view that will be used to anchor this popup.
371c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
372c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return The popup's anchor view
373c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
374c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public View getAnchorView() {
375c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mDropDownAnchorView;
376c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
377c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
378c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
379c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Sets the popup's anchor view. This popup will always be positioned relative to
380c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * the anchor view when shown.
381c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
382c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param anchor The view to use as an anchor.
383c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
384c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setAnchorView(View anchor) {
385c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mDropDownAnchorView = anchor;
386c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
387c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
388c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
389c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return The horizontal offset of the popup from its anchor in pixels.
390c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
391c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public int getHorizontalOffset() {
392c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mDropDownHorizontalOffset;
393c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
394c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
395c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
396c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Set the horizontal offset of this popup from its anchor view in pixels.
397c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
398a984b38df5cfe6db0ba792bf2a6221f6b6072448Adam Powell     * @param offset The horizontal offset of the popup from its anchor.
399c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
400c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setHorizontalOffset(int offset) {
401c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mDropDownHorizontalOffset = offset;
402c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
403c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
404c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
405c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return The vertical offset of the popup from its anchor in pixels.
406c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
407c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public int getVerticalOffset() {
4088132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell        if (!mDropDownVerticalOffsetSet) {
4098132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell            return 0;
4108132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell        }
411c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mDropDownVerticalOffset;
412c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
413c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
414c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
415c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Set the vertical offset of this popup from its anchor view in pixels.
416c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
417a984b38df5cfe6db0ba792bf2a6221f6b6072448Adam Powell     * @param offset The vertical offset of the popup from its anchor.
418c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
419c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setVerticalOffset(int offset) {
420c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mDropDownVerticalOffset = offset;
4218132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell        mDropDownVerticalOffsetSet = true;
422c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
423c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
424c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
425c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return The width of the popup window in pixels.
426c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
427c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public int getWidth() {
428c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mDropDownWidth;
429c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
430c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
431c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
432c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Sets the width of the popup window in pixels. Can also be {@link #MATCH_PARENT}
433c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * or {@link #WRAP_CONTENT}.
434c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
435c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param width Width of the popup window.
436c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
437c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setWidth(int width) {
438c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mDropDownWidth = width;
439c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
440c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
441c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
4424267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell     * Sets the width of the popup window by the size of its content. The final width may be
4434267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell     * larger to accommodate styled window dressing.
4444267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell     *
4454267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell     * @param width Desired width of content in pixels.
4464267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell     */
4474267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell    public void setContentWidth(int width) {
4484267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell        Drawable popupBackground = mPopup.getBackground();
4494267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell        if (popupBackground != null) {
450a39b987bb761899636ae1e3669d1343499d04ebdAdam Powell            popupBackground.getPadding(mTempRect);
451a39b987bb761899636ae1e3669d1343499d04ebdAdam Powell            mDropDownWidth = mTempRect.left + mTempRect.right + width;
45262e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell        } else {
45362e2bdecc21819a71c04204f20fc051886fdabd6Adam Powell            setWidth(width);
4544267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell        }
4554267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell    }
4564267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell
4574267534d1c42af847ed0cefd1c88c99f66b36571Adam Powell    /**
458c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return The height of the popup window in pixels.
459c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
460c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public int getHeight() {
461c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mDropDownHeight;
462c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
463c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
464c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
465c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Sets the height of the popup window in pixels. Can also be {@link #MATCH_PARENT}.
466c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
467c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param height Height of the popup window.
468c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
469c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setHeight(int height) {
470c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mDropDownHeight = height;
471c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
472c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
473c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
474c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Sets a listener to receive events when a list item is clicked.
475c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
476c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param clickListener Listener to register
477c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
478c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see ListView#setOnItemClickListener(android.widget.AdapterView.OnItemClickListener)
479c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
480c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setOnItemClickListener(AdapterView.OnItemClickListener clickListener) {
481c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mItemClickListener = clickListener;
482c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
483c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
484c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
485c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Sets a listener to receive events when a list item is selected.
486c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
487c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param selectedListener Listener to register.
488c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
489c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see ListView#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener)
490c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
491c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener selectedListener) {
492c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mItemSelectedListener = selectedListener;
493c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
494c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
495c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
496c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Set a view to act as a user prompt for this popup window. Where the prompt view will appear
497c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * is controlled by {@link #setPromptPosition(int)}.
498c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
499c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param prompt View to use as an informational prompt.
500c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
501c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setPromptView(View prompt) {
502c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        boolean showing = isShowing();
503c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (showing) {
504c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            removePromptView();
505c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
506c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPromptView = prompt;
507c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (showing) {
508c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            show();
509c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
510c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
511c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
512c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
513c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Post a {@link #show()} call to the UI thread.
514c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
515c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void postShow() {
516c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mHandler.post(mShowDropDownRunnable);
517c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
518c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
519c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
520c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Show the popup list. If the list is already showing, this method
521c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * will recalculate the popup's size and position.
522c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
523c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void show() {
524c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        int height = buildDropDown();
525c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
526c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        int widthSpec = 0;
527c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        int heightSpec = 0;
528c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
529c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        boolean noInputMethod = isInputMethodNotNeeded();
530348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell        mPopup.setAllowScrollingAnchorParent(!noInputMethod);
531c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
532c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (mPopup.isShowing()) {
533c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) {
534c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                // The call to PopupWindow's update method below can accept -1 for any
535c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                // value you do not want to update.
536c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                widthSpec = -1;
537c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            } else if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) {
538c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                widthSpec = getAnchorView().getWidth();
539c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            } else {
540c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                widthSpec = mDropDownWidth;
541c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
542c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
543c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
544c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                // The call to PopupWindow's update method below can accept -1 for any
545c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                // value you do not want to update.
546c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.MATCH_PARENT;
547c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                if (noInputMethod) {
548c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mPopup.setWindowLayoutMode(
549c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                            mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ?
550c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                                    ViewGroup.LayoutParams.MATCH_PARENT : 0, 0);
551c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                } else {
552c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mPopup.setWindowLayoutMode(
553c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                            mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT ?
554c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                                    ViewGroup.LayoutParams.MATCH_PARENT : 0,
555c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                            ViewGroup.LayoutParams.MATCH_PARENT);
556c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                }
557c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) {
558c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                heightSpec = height;
559c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            } else {
560c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                heightSpec = mDropDownHeight;
561c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
562c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
563c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible);
564c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
565c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mPopup.update(getAnchorView(), mDropDownHorizontalOffset,
566c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mDropDownVerticalOffset, widthSpec, heightSpec);
567c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        } else {
568c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) {
569c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                widthSpec = ViewGroup.LayoutParams.MATCH_PARENT;
570c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            } else {
571c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) {
572c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mPopup.setWidth(getAnchorView().getWidth());
573c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                } else {
574c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mPopup.setWidth(mDropDownWidth);
575c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                }
576c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
577c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
578c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
579c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                heightSpec = ViewGroup.LayoutParams.MATCH_PARENT;
580c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            } else {
581c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) {
582c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mPopup.setHeight(height);
583c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                } else {
584c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mPopup.setHeight(mDropDownHeight);
585c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                }
586c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
587c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
588c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mPopup.setWindowLayoutMode(widthSpec, heightSpec);
58956c2d337e02a275397fc9d0460dca90977f199acAdam Powell            mPopup.setClipToScreenEnabled(true);
590c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
591c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // use outside touchable to dismiss drop down when touching outside of it, so
592c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // only set this if the dropdown is not always visible
593c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible);
594c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mPopup.setTouchInterceptor(mTouchInterceptor);
595c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mPopup.showAsDropDown(getAnchorView(),
596c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mDropDownHorizontalOffset, mDropDownVerticalOffset);
597c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mDropDownList.setSelection(ListView.INVALID_POSITION);
598c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
599c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (!mModal || mDropDownList.isInTouchMode()) {
600c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                clearListSelection();
601c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
602c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (!mModal) {
603c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mHandler.post(mHideSelector);
604c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
605c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
606c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
607c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
608c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
609c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Dismiss the popup window.
610c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
611c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void dismiss() {
612c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.dismiss();
613c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        removePromptView();
614c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setContentView(null);
615c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mDropDownList = null;
616ca51e8788a58f2af3525b7214a675f2d0233e5daAdam Powell        mHandler.removeCallbacks(mResizePopupRunnable);
617c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
618c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
6196c6f575423d6718c3ff322224c1520901ce881e1Adam Powell    /**
6206c6f575423d6718c3ff322224c1520901ce881e1Adam Powell     * Set a listener to receive a callback when the popup is dismissed.
6216c6f575423d6718c3ff322224c1520901ce881e1Adam Powell     *
6226c6f575423d6718c3ff322224c1520901ce881e1Adam Powell     * @param listener Listener that will be notified when the popup is dismissed.
6236c6f575423d6718c3ff322224c1520901ce881e1Adam Powell     */
6246c6f575423d6718c3ff322224c1520901ce881e1Adam Powell    public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
6256c6f575423d6718c3ff322224c1520901ce881e1Adam Powell        mPopup.setOnDismissListener(listener);
6266c6f575423d6718c3ff322224c1520901ce881e1Adam Powell    }
6276c6f575423d6718c3ff322224c1520901ce881e1Adam Powell
628c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private void removePromptView() {
629c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (mPromptView != null) {
630c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            final ViewParent parent = mPromptView.getParent();
631c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (parent instanceof ViewGroup) {
632c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                final ViewGroup group = (ViewGroup) parent;
633c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                group.removeView(mPromptView);
634c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
635c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
636c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
637c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
638c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
639c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Control how the popup operates with an input method: one of
640c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * {@link #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED},
641c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * or {@link #INPUT_METHOD_NOT_NEEDED}.
642c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
643c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * <p>If the popup is showing, calling this method will take effect only
644c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * the next time the popup is shown or through a manual call to the {@link #show()}
645c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * method.</p>
646c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
647c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #getInputMethodMode()
648c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #show()
649c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
650c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setInputMethodMode(int mode) {
651c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        mPopup.setInputMethodMode(mode);
652c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
653c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
654c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
655c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Return the current value in {@link #setInputMethodMode(int)}.
656c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
657c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #setInputMethodMode(int)
658c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
659c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public int getInputMethodMode() {
660c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.getInputMethodMode();
661c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
662c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
663c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
664c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Set the selected position of the list.
665c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Only valid when {@link #isShowing()} == {@code true}.
666c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
667c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param position List position to set as selected.
668c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
669c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void setSelection(int position) {
670c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        DropDownListView list = mDropDownList;
671c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (isShowing() && list != null) {
672c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            list.mListSelectionHidden = false;
673c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            list.setSelection(position);
674c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (list.getChoiceMode() != ListView.CHOICE_MODE_NONE) {
675c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                list.setItemChecked(position, true);
676c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
677c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
678c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
679c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
680c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
681c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Clear any current list selection.
682c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Only valid when {@link #isShowing()} == {@code true}.
683c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
684c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public void clearListSelection() {
685c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        final DropDownListView list = mDropDownList;
686c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (list != null) {
687c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // WARNING: Please read the comment where mListSelectionHidden is declared
688c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            list.mListSelectionHidden = true;
689c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            list.hideSelector();
690c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            list.requestLayout();
691c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
692c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
693c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
694c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
695c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return {@code true} if the popup is currently showing, {@code false} otherwise.
696c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
697c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public boolean isShowing() {
698c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.isShowing();
699c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
700c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
701c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
702c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return {@code true} if this popup is configured to assume the user does not need
703c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * to interact with the IME while it is showing, {@code false} otherwise.
704c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
705c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public boolean isInputMethodNotNeeded() {
706c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mPopup.getInputMethodMode() == INPUT_METHOD_NOT_NEEDED;
707c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
708c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
709c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
710c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Perform an item click operation on the specified list adapter position.
711c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
712c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param position Adapter position for performing the click
713c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return true if the click action could be performed, false if not.
714c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *         (e.g. if the popup was not showing, this method would return false.)
715c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
716c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public boolean performItemClick(int position) {
717c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (isShowing()) {
718c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (mItemClickListener != null) {
719c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                final DropDownListView list = mDropDownList;
720c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                final View child = list.getChildAt(position - list.getFirstVisiblePosition());
721cdee446075811e871fc2af295377bd99c100d16dAdam Powell                final ListAdapter adapter = list.getAdapter();
722cdee446075811e871fc2af295377bd99c100d16dAdam Powell                mItemClickListener.onItemClick(list, child, position, adapter.getItemId(position));
723c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
724c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return true;
725c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
726c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return false;
727c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
728c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
729c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
730c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return The currently selected item or null if the popup is not showing.
731c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
732c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public Object getSelectedItem() {
733c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (!isShowing()) {
734c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return null;
735c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
736c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mDropDownList.getSelectedItem();
737c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
738c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
739c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
740c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return The position of the currently selected item or {@link ListView#INVALID_POSITION}
741c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * if {@link #isShowing()} == {@code false}.
742c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
743c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see ListView#getSelectedItemPosition()
744c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
745c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public int getSelectedItemPosition() {
746c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (!isShowing()) {
747c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return ListView.INVALID_POSITION;
748c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
749c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mDropDownList.getSelectedItemPosition();
750c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
751c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
752c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
753c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return The ID of the currently selected item or {@link ListView#INVALID_ROW_ID}
754c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * if {@link #isShowing()} == {@code false}.
755c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
756c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see ListView#getSelectedItemId()
757c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
758c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public long getSelectedItemId() {
759c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (!isShowing()) {
760c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return ListView.INVALID_ROW_ID;
761c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
762c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mDropDownList.getSelectedItemId();
763c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
764c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
765c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
766c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return The View for the currently selected item or null if
767c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * {@link #isShowing()} == {@code false}.
768c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
769c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see ListView#getSelectedView()
770c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
771c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public View getSelectedView() {
772c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (!isShowing()) {
773c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return null;
774c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
775c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mDropDownList.getSelectedView();
776c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
777c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
778c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
779c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return The {@link ListView} displayed within the popup window.
780c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Only valid when {@link #isShowing()} == {@code true}.
781c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
782c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public ListView getListView() {
783c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return mDropDownList;
784c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
785c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
786c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
787348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * The maximum number of list items that can be visible and still have
788348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * the list expand when touched.
789348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     *
790348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     * @param max Max number of items that can be visible and still allow the list to expand.
791348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell     */
792348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    void setListItemExpandMax(int max) {
793348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell        mListItemExpandMaximum = max;
794348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    }
795348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell
796348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell    /**
7978d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown     * Filter key down events. By forwarding key down events to this function,
798c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * views using non-modal ListPopupWindow can have it handle key selection of items.
799c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
800c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param keyCode keyCode param passed to the host view's onKeyDown
801c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param event event param passed to the host view's onKeyDown
802c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return true if the event was handled, false if it was ignored.
803c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
804c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #setModal(boolean)
805c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
806c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public boolean onKeyDown(int keyCode, KeyEvent event) {
807c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        // when the drop down is shown, we drive it directly
808c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (isShowing()) {
809c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // the key events are forwarded to the list in the drop down view
810c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // note that ListView handles space but we don't want that to happen
811c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // also if selection is not currently in the drop down, then don't
812c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // let center or enter presses go there since that would cause it
813c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // to select one of its items
814c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (keyCode != KeyEvent.KEYCODE_SPACE
815c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    && (mDropDownList.getSelectedItemPosition() >= 0
816c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                            || (keyCode != KeyEvent.KEYCODE_ENTER
817c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                                    && keyCode != KeyEvent.KEYCODE_DPAD_CENTER))) {
818c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                int curIndex = mDropDownList.getSelectedItemPosition();
819c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                boolean consumed;
820c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
821c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                final boolean below = !mPopup.isAboveAnchor();
822c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
823c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                final ListAdapter adapter = mAdapter;
824c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
825c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                boolean allEnabled;
826c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                int firstItem = Integer.MAX_VALUE;
827c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                int lastItem = Integer.MIN_VALUE;
828c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
829c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                if (adapter != null) {
830c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    allEnabled = adapter.areAllItemsEnabled();
831c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    firstItem = allEnabled ? 0 :
832c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                            mDropDownList.lookForSelectablePosition(0, true);
833c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    lastItem = allEnabled ? adapter.getCount() - 1 :
834c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                            mDropDownList.lookForSelectablePosition(adapter.getCount() - 1, false);
835c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                }
836c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
837c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                if ((below && keyCode == KeyEvent.KEYCODE_DPAD_UP && curIndex <= firstItem) ||
838c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        (!below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN && curIndex >= lastItem)) {
839c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // When the selection is at the top, we block the key
840c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // event to prevent focus from moving.
841c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    clearListSelection();
842c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
843c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    show();
844c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    return true;
845c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                } else {
846c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // WARNING: Please read the comment where mListSelectionHidden
847c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    //          is declared
848c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mDropDownList.mListSelectionHidden = false;
849c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                }
850c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
851c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                consumed = mDropDownList.onKeyDown(keyCode, event);
852c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                if (DEBUG) Log.v(TAG, "Key down: code=" + keyCode + " list consumed=" + consumed);
853c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
854c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                if (consumed) {
855c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // If it handled the key event, then the user is
856c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // navigating in the list, so we should put it in front.
857c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
858c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // Here's a little trick we need to do to make sure that
859c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // the list view is actually showing its focus indicator,
860c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // by ensuring it has focus and getting its window out
861c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // of touch mode.
862c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mDropDownList.requestFocusFromTouch();
863c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    show();
864c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
865c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    switch (keyCode) {
866c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        // avoid passing the focus from the text view to the
867c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        // next component
868c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        case KeyEvent.KEYCODE_ENTER:
869c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        case KeyEvent.KEYCODE_DPAD_CENTER:
870c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        case KeyEvent.KEYCODE_DPAD_DOWN:
871c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        case KeyEvent.KEYCODE_DPAD_UP:
872c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                            return true;
873c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    }
874c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                } else {
875c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    if (below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
876c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        // when the selection is at the bottom, we block the
877c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        // event to avoid going to the next focusable widget
878c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        if (curIndex == lastItem) {
879c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                            return true;
880c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        }
881c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    } else if (!below && keyCode == KeyEvent.KEYCODE_DPAD_UP &&
882c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                            curIndex == firstItem) {
883c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        return true;
884c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    }
885c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                }
886c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
887c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
888c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
889c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return false;
890c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
891c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
892c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
893c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Filter key down events. By forwarding key up events to this function,
894c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * views using non-modal ListPopupWindow can have it handle key selection of items.
895c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
896c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param keyCode keyCode param passed to the host view's onKeyUp
897c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param event event param passed to the host view's onKeyUp
898c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return true if the event was handled, false if it was ignored.
899c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
900c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #setModal(boolean)
901c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
902c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public boolean onKeyUp(int keyCode, KeyEvent event) {
903c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (isShowing() && mDropDownList.getSelectedItemPosition() >= 0) {
904c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            boolean consumed = mDropDownList.onKeyUp(keyCode, event);
905c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (consumed) {
906c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                switch (keyCode) {
907c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // if the list accepts the key events and the key event
908c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // was a click, the text view gets the selected item
909c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // from the drop down as its content
910c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    case KeyEvent.KEYCODE_ENTER:
911c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    case KeyEvent.KEYCODE_DPAD_CENTER:
912c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        dismiss();
913c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        break;
914c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                }
915c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
916c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return consumed;
917c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
918c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return false;
919c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
920c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
921c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
922c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * Filter pre-IME key events. By forwarding {@link View#onKeyPreIme(int, KeyEvent)}
923c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * events to this function, views using ListPopupWindow can have it dismiss the popup
924c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * when the back key is pressed.
925c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
926c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param keyCode keyCode param passed to the host view's onKeyPreIme
927c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @param event event param passed to the host view's onKeyPreIme
928c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return true if the event was handled, false if it was ignored.
929c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
930c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @see #setModal(boolean)
931c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
932c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
933c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (keyCode == KeyEvent.KEYCODE_BACK && isShowing()) {
934c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // special case for the back key, we do not even try to send it
935c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // to the drop down list but instead, consume it immediately
936c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            final View anchorView = mDropDownAnchorView;
937c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
938b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState();
939b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                if (state != null) {
940b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    state.startTracking(event, this);
941b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                }
942c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                return true;
943c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            } else if (event.getAction() == KeyEvent.ACTION_UP) {
944b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                KeyEvent.DispatcherState state = anchorView.getKeyDispatcherState();
945b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                if (state != null) {
946b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                    state.handleUpEvent(event);
947b3ea92235c9ccc1ff295839a8f324dcd1c83dd6fJeff Brown                }
948c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                if (event.isTracking() && !event.isCanceled()) {
949c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    dismiss();
950c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    return true;
951c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                }
952c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
953c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
954c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return false;
955c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
956c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
957c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
958c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * <p>Builds the popup window's content and returns the height the popup
959c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * should have. Returns -1 when the content already exists.</p>
960c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     *
961c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * @return the content's height or -1 if content already exists
962c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
963c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private int buildDropDown() {
964c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        ViewGroup dropDownView;
965c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        int otherHeights = 0;
966c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
967c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (mDropDownList == null) {
968c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            Context context = mContext;
969c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
970c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            /**
971c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell             * This Runnable exists for the sole purpose of checking if the view layout has got
972c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell             * completed and if so call showDropDown to display the drop down. This is used to show
973c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell             * the drop down as soon as possible after user opens up the search dialog, without
974c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell             * waiting for the normal UI pipeline to do it's job which is slower than this method.
975c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell             */
976c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mShowDropDownRunnable = new Runnable() {
977c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                public void run() {
978c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    // View layout should be all done before displaying the drop down.
979c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    View view = getAnchorView();
980c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    if (view != null && view.getWindowToken() != null) {
981c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        show();
982c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    }
983c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                }
984c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            };
985c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
986c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mDropDownList = new DropDownListView(context, !mModal);
987c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (mDropDownListHighlight != null) {
988c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mDropDownList.setSelector(mDropDownListHighlight);
989c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
990c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mDropDownList.setAdapter(mAdapter);
991c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mDropDownList.setOnItemClickListener(mItemClickListener);
992c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mDropDownList.setFocusable(true);
993c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mDropDownList.setFocusableInTouchMode(true);
994c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mDropDownList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
995c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                public void onItemSelected(AdapterView<?> parent, View view,
996c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        int position, long id) {
997c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
998c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    if (position != -1) {
999c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        DropDownListView dropDownList = mDropDownList;
1000c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1001c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        if (dropDownList != null) {
1002c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                            dropDownList.mListSelectionHidden = false;
1003c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        }
1004c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    }
1005c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                }
1006c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1007c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                public void onNothingSelected(AdapterView<?> parent) {
1008c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                }
1009c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            });
1010c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mDropDownList.setOnScrollListener(mScrollListener);
1011c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1012c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (mItemSelectedListener != null) {
1013c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mDropDownList.setOnItemSelectedListener(mItemSelectedListener);
1014c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
1015c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1016c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            dropDownView = mDropDownList;
1017c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1018c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            View hintView = mPromptView;
1019c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (hintView != null) {
1020c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                // if an hint has been specified, we accomodate more space for it and
1021c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                // add a text view in the drop down menu, at the bottom of the list
1022c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                LinearLayout hintContainer = new LinearLayout(context);
1023c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                hintContainer.setOrientation(LinearLayout.VERTICAL);
1024c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1025c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                LinearLayout.LayoutParams hintParams = new LinearLayout.LayoutParams(
1026c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        ViewGroup.LayoutParams.MATCH_PARENT, 0, 1.0f
1027c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                );
1028c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1029c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                switch (mPromptPosition) {
1030c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                case POSITION_PROMPT_BELOW:
1031c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    hintContainer.addView(dropDownView, hintParams);
1032c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    hintContainer.addView(hintView);
1033c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    break;
1034c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1035c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                case POSITION_PROMPT_ABOVE:
1036c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    hintContainer.addView(hintView);
1037c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    hintContainer.addView(dropDownView, hintParams);
1038c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    break;
1039c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1040c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                default:
1041c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    Log.e(TAG, "Invalid hint position " + mPromptPosition);
1042c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    break;
1043c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                }
1044c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1045c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                // measure the hint's height to find how much more vertical space
1046c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                // we need to add to the drop down's height
1047c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                int widthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.AT_MOST);
1048c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                int heightSpec = MeasureSpec.UNSPECIFIED;
1049c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                hintView.measure(widthSpec, heightSpec);
1050c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1051c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams();
1052c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                otherHeights = hintView.getMeasuredHeight() + hintParams.topMargin
1053c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        + hintParams.bottomMargin;
1054c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1055c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                dropDownView = hintContainer;
1056c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
1057c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1058c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mPopup.setContentView(dropDownView);
1059c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        } else {
1060c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            dropDownView = (ViewGroup) mPopup.getContentView();
1061c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            final View view = mPromptView;
1062c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (view != null) {
1063c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                LinearLayout.LayoutParams hintParams =
1064c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        (LinearLayout.LayoutParams) view.getLayoutParams();
1065c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                otherHeights = view.getMeasuredHeight() + hintParams.topMargin
1066c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                        + hintParams.bottomMargin;
1067c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
1068c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1069c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
10708132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell        // getMaxAvailableHeight() subtracts the padding, so we put it back
1071c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        // to get the available height for the whole window
1072c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        int padding = 0;
1073c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        Drawable background = mPopup.getBackground();
1074c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (background != null) {
1075c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            background.getPadding(mTempRect);
1076c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            padding = mTempRect.top + mTempRect.bottom;
10778132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell
10788132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell            // If we don't have an explicit vertical offset, determine one from the window
10798132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell            // background so that content will line up.
10808132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell            if (!mDropDownVerticalOffsetSet) {
10818132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell                mDropDownVerticalOffset = -mTempRect.top;
10828132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell            }
1083c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1084c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
10858132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell        // Max height available on the screen for a popup.
10868132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell        boolean ignoreBottomDecorations =
10878132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell                mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED;
10888132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell        final int maxHeight = mPopup.getMaxAvailableHeight(
10898132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell                getAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations);
10908132ba5e2e82d02697ef0570142abb8fc8054a67Adam Powell
1091c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (mDropDownAlwaysVisible || mDropDownHeight == ViewGroup.LayoutParams.MATCH_PARENT) {
1092c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return maxHeight + padding;
1093c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1094c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1095c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        final int listContent = mDropDownList.measureHeightOfChildren(MeasureSpec.UNSPECIFIED,
1096a7845ed44a3722e7d96ca9b677be213da7e8c8feAdam Powell                0, ListView.NO_POSITION, maxHeight - otherHeights, -1);
1097c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        // add padding only if the list has items in it, that way we don't show
1098c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        // the popup if it is not needed
1099c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        if (listContent > 0) otherHeights += padding;
1100c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1101c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        return listContent + otherHeights;
1102c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
1103c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1104c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    /**
1105c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * <p>Wrapper class for a ListView. This wrapper can hijack the focus to
1106c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * make sure the list uses the appropriate drawables and states when
1107c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * displayed on screen within a drop down. The focus is never actually
1108c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     * passed to the drop down in this mode; the list only looks focused.</p>
1109c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell     */
1110c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private static class DropDownListView extends ListView {
1111c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        private static final String TAG = ListPopupWindow.TAG + ".DropDownListView";
1112c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        /*
1113c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * WARNING: This is a workaround for a touch mode issue.
1114c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         *
1115c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * Touch mode is propagated lazily to windows. This causes problems in
1116c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * the following scenario:
1117c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * - Type something in the AutoCompleteTextView and get some results
1118c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * - Move down with the d-pad to select an item in the list
1119c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * - Move up with the d-pad until the selection disappears
1120c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * - Type more text in the AutoCompleteTextView *using the soft keyboard*
1121c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         *   and get new results; you are now in touch mode
1122c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * - The selection comes back on the first item in the list, even though
1123c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         *   the list is supposed to be in touch mode
1124c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         *
1125c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * Using the soft keyboard triggers the touch mode change but that change
1126c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * is propagated to our window only after the first list layout, therefore
1127c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * after the list attempts to resurrect the selection.
1128c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         *
1129c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * The trick to work around this issue is to pretend the list is in touch
1130c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * mode when we know that the selection should not appear, that is when
1131c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * we know the user moved the selection away from the list.
1132c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         *
1133c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * This boolean is set to true whenever we explicitly hide the list's
1134c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * selection and reset to false whenever we know the user moved the
1135c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * selection back to the list.
1136c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         *
1137c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * When this boolean is true, isInTouchMode() returns true, otherwise it
1138c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * returns super.isInTouchMode().
1139c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         */
1140c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        private boolean mListSelectionHidden;
1141c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1142c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        /**
1143c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * True if this wrapper should fake focus.
1144c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         */
1145c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        private boolean mHijackFocus;
1146c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1147c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        /**
1148c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * <p>Creates a new list view wrapper.</p>
1149c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         *
1150c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * @param context this view's context
1151c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         */
1152c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        public DropDownListView(Context context, boolean hijackFocus) {
1153c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            super(context, null, com.android.internal.R.attr.dropDownListViewStyle);
1154c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            mHijackFocus = hijackFocus;
1155b1818e83f4a81bc4e4e30b99bb48830415be731bAmith Yamasani            // TODO: Add an API to control this
1156b1818e83f4a81bc4e4e30b99bb48830415be731bAmith Yamasani            setCacheColorHint(0); // Transparent, since the background drawable could be anything.
1157c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1158c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1159c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        /**
1160c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * <p>Avoids jarring scrolling effect by ensuring that list elements
1161c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * made of a text view fit on a single line.</p>
1162c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         *
1163c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * @param position the item index in the list to get a view for
1164c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * @return the view for the specified item
1165c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         */
1166c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        @Override
1167c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        View obtainView(int position, boolean[] isScrap) {
1168c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            View view = super.obtainView(position, isScrap);
1169c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1170c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (view instanceof TextView) {
1171c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                ((TextView) view).setHorizontallyScrolling(true);
1172c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
1173c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1174c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return view;
1175c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1176c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1177c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        @Override
1178c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        public boolean isInTouchMode() {
1179c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            // WARNING: Please read the comment where mListSelectionHidden is declared
1180c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return (mHijackFocus && mListSelectionHidden) || super.isInTouchMode();
1181c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1182c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1183c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        /**
1184c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * <p>Returns the focus state in the drop down.</p>
1185c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         *
1186c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * @return true always if hijacking focus
1187c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         */
1188c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        @Override
1189c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        public boolean hasWindowFocus() {
1190c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return mHijackFocus || super.hasWindowFocus();
1191c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1192c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1193c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        /**
1194c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * <p>Returns the focus state in the drop down.</p>
1195c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         *
1196c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * @return true always if hijacking focus
1197c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         */
1198c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        @Override
1199c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        public boolean isFocused() {
1200c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return mHijackFocus || super.isFocused();
1201c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1202c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1203c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        /**
1204c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * <p>Returns the focus state in the drop down.</p>
1205c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         *
1206c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         * @return true always if hijacking focus
1207c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell         */
1208c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        @Override
1209c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        public boolean hasFocus() {
1210c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return mHijackFocus || super.hasFocus();
1211c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1212c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
1213c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1214c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private class PopupDataSetObserver extends DataSetObserver {
1215c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        @Override
1216c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        public void onChanged() {
1217c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (isShowing()) {
1218c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                // Resize the popup to fit new content
1219c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                show();
1220c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
1221c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1222c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1223c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        @Override
1224c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        public void onInvalidated() {
1225c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            dismiss();
1226c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1227c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
1228c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1229c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private class ListSelectorHider implements Runnable {
1230c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        public void run() {
1231c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            clearListSelection();
1232c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1233c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
1234c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1235c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private class ResizePopupRunnable implements Runnable {
1236c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        public void run() {
1237348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell            if (mDropDownList != null && mDropDownList.getCount() > mDropDownList.getChildCount() &&
1238348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell                    mDropDownList.getChildCount() <= mListItemExpandMaximum) {
1239348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell                mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
1240348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell                show();
1241348e69cfabec21ccfbe708df06f0a7ea541a3053Adam Powell            }
1242c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1243c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
1244c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1245c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private class PopupTouchInterceptor implements OnTouchListener {
1246c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        public boolean onTouch(View v, MotionEvent event) {
1247c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            final int action = event.getAction();
1248c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            final int x = (int) event.getX();
1249c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            final int y = (int) event.getY();
1250c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1251c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (action == MotionEvent.ACTION_DOWN &&
1252c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    mPopup != null && mPopup.isShowing() &&
1253711734a2f8d7529df0ed1bce36da651fc835c144Gilles Debunne                    (x >= 0 && x < mPopup.getWidth() && y >= 0 && y < mPopup.getHeight())) {
1254c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mHandler.postDelayed(mResizePopupRunnable, EXPAND_LIST_TIMEOUT);
1255c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            } else if (action == MotionEvent.ACTION_UP) {
1256c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mHandler.removeCallbacks(mResizePopupRunnable);
1257c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
1258c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            return false;
1259c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1260c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
1261c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1262c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    private class PopupScrollListener implements ListView.OnScrollListener {
1263c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
1264c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                int totalItemCount) {
1265c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1266c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1267c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell
1268c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        public void onScrollStateChanged(AbsListView view, int scrollState) {
1269c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            if (scrollState == SCROLL_STATE_TOUCH_SCROLL &&
1270c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                    !isInputMethodNotNeeded() && mPopup.getContentView() != null) {
1271c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mHandler.removeCallbacks(mResizePopupRunnable);
1272c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell                mResizePopupRunnable.run();
1273c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell            }
1274c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell        }
1275c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell    }
1276c3fa6304c997ccecf8ed15a4cbb7bd245128f3c3Adam Powell}
1277