13565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani/* 23565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Copyright (C) 2010 The Android Open Source Project 33565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 43565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Licensed under the Apache License, Version 2.0 (the "License"); 53565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * you may not use this file except in compliance with the License. 63565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * You may obtain a copy of the License at 73565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 83565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * http://www.apache.org/licenses/LICENSE-2.0 93565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Unless required by applicable law or agreed to in writing, software 113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * distributed under the License is distributed on an "AS IS" BASIS, 123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * See the License for the specific language governing permissions and 143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * limitations under the License. 153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 17da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownpackage android.support.v7.internal.widget; 183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.content.Context; 203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.content.res.Resources; 213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.database.DataSetObserver; 223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.graphics.Rect; 233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.graphics.drawable.Drawable; 243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.os.Handler; 25da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.appcompat.R; 263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.text.TextUtils; 273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.util.AttributeSet; 283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.util.Log; 293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.util.SparseArray; 303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.KeyEvent; 313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.MotionEvent; 323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.View; 333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.View.MeasureSpec; 343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.View.OnTouchListener; 353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.ViewGroup; 363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.view.ViewParent; 373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport android.widget.*; 383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport java.lang.reflect.Field; 403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport java.util.ArrayList; 413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport java.util.List; 423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewaniimport java.util.Locale; 433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani/** 4520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * A ListPopupWindow anchors itself to a host view and displays a list of choices. 463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 4720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * <p>ListPopupWindow contains a number of tricky behaviors surrounding positioning, scrolling 4820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * parents to fit the dropdown, interacting sanely with the IME if present, and others. 493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see android.widget.AutoCompleteTextView 513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see android.widget.Spinner 5289208232f3b5d1451408d787872504a190bc7ee0Chris Banes * 5389208232f3b5d1451408d787872504a190bc7ee0Chris Banes * @hide 543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewanipublic class ListPopupWindow { 5620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private static final String TAG = "ListPopupWindow"; 583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private static final boolean DEBUG = false; 593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 6120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * This value controls the length of time that the user must leave a pointer down without 6220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * scrolling to expand the autocomplete dropdown list to cover the IME. 633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private static final int EXPAND_LIST_TIMEOUT = 250; 653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private Context mContext; 673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private PopupWindow mPopup; 683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private ListAdapter mAdapter; 693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private DropDownListView mDropDownList; 703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private int mDropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT; 723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private int mDropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT; 733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private int mDropDownHorizontalOffset; 743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private int mDropDownVerticalOffset; 753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private boolean mDropDownVerticalOffsetSet; 763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private boolean mDropDownAlwaysVisible = false; 783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private boolean mForceIgnoreOutsideTouch = false; 793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int mListItemExpandMaximum = Integer.MAX_VALUE; 803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private View mPromptView; 823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private int mPromptPosition = POSITION_PROMPT_ABOVE; 833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private DataSetObserver mObserver; 853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private View mDropDownAnchorView; 873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private Drawable mDropDownListHighlight; 893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private AdapterView.OnItemClickListener mItemClickListener; 913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private AdapterView.OnItemSelectedListener mItemSelectedListener; 923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private final ResizePopupRunnable mResizePopupRunnable = new ResizePopupRunnable(); 943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private final PopupTouchInterceptor mTouchInterceptor = new PopupTouchInterceptor(); 953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private final PopupScrollListener mScrollListener = new PopupScrollListener(); 963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private final ListSelectorHider mHideSelector = new ListSelectorHider(); 973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private Runnable mShowDropDownRunnable; 983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private Handler mHandler = new Handler(); 1003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private Rect mTempRect = new Rect(); 1023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private boolean mModal; 1043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private int mLayoutDirection; 1063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 1083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * The provided prompt view should appear above list content. 1093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 1103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #setPromptPosition(int) 1113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #getPromptPosition() 1123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #setPromptView(View) 1133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 1143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public static final int POSITION_PROMPT_ABOVE = 0; 1153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 1173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * The provided prompt view should appear below list content. 1183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 1193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #setPromptPosition(int) 1203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #getPromptPosition() 1213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #setPromptView(View) 1223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 1233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public static final int POSITION_PROMPT_BELOW = 1; 1243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 12620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Alias for {@link ViewGroup.LayoutParams#FILL_PARENT}. If used to specify a popup width, the 12720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * popup will match the width of the anchor view. If used to specify a popup height, the popup 12820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * will fill available space. 1293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 1303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public static final int FILL_PARENT = ViewGroup.LayoutParams.FILL_PARENT; 1313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 13320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Alias for {@link ViewGroup.LayoutParams#WRAP_CONTENT}. If used to specify a popup width, the 13420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * popup will use the width of its content. 1353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 1363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public static final int WRAP_CONTENT = ViewGroup.LayoutParams.WRAP_CONTENT; 1373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 13920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Mode for {@link #setInputMethodMode(int)}: the requirements for the input method should be 14020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * based on the focusability of the popup. That is if it is focusable than it needs to work 14120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * with the input method, else it doesn't. 1423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 1433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public static final int INPUT_METHOD_FROM_FOCUSABLE = PopupWindow.INPUT_METHOD_FROM_FOCUSABLE; 1443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 14620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Mode for {@link #setInputMethodMode(int)}: this popup always needs to work with an input 14720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * method, regardless of whether it is focusable. This means that it will always be displayed 14820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * so that the user can also operate the input method while it is shown. 1493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 1503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public static final int INPUT_METHOD_NEEDED = PopupWindow.INPUT_METHOD_NEEDED; 1513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 15320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Mode for {@link #setInputMethodMode(int)}: this popup never needs to work with an input 15420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * method, regardless of whether it is focusable. This means that it will always be displayed 15520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * to use as much space on the screen as needed, regardless of whether this covers the input 15620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * method. 1573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 1583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public static final int INPUT_METHOD_NOT_NEEDED = PopupWindow.INPUT_METHOD_NOT_NEEDED; 1593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 16120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Create a new, empty popup window capable of displaying items from a ListAdapter. Backgrounds 16220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * should be set using {@link #setBackgroundDrawable(Drawable)}. 1633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 1643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param context Context used for contained views. 1653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 1663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public ListPopupWindow(Context context) { 167ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns this(context, null, R.attr.listPopupWindowStyle); 1683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 1693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 17120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Create a new, empty popup window capable of displaying items from a ListAdapter. Backgrounds 17220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * should be set using {@link #setBackgroundDrawable(Drawable)}. 1733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 1743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param context Context used for contained views. 17520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param attrs Attributes from inflating parent views used to style the popup. 1763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 1773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public ListPopupWindow(Context context, AttributeSet attrs) { 178ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns this(context, attrs, R.attr.listPopupWindowStyle); 1793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 1803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 18220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Create a new, empty popup window capable of displaying items from a ListAdapter. Backgrounds 18320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * should be set using {@link #setBackgroundDrawable(Drawable)}. 1843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 18520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param context Context used for contained views. 18620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param attrs Attributes from inflating parent views used to style the popup. 1873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param defStyleAttr Default style attribute to use for popup content. 1883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 1893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public ListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr) { 1903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mContext = context; 191ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns mPopup = new PopupWindow(context, attrs, defStyleAttr); 1923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 1933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // Set the default layout direction to match the default locale one 1943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final Locale locale = mContext.getResources().getConfiguration().locale; 1953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 196ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns } 1973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 1983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 19920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Sets the adapter that provides the data and the views to represent the data in this popup 20020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * window. 2013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 2023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param adapter The adapter to use to create this window's content. 2033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 2043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setAdapter(ListAdapter adapter) { 2053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mObserver == null) { 2063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mObserver = new PopupDataSetObserver(); 2073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else if (mAdapter != null) { 2083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mAdapter.unregisterDataSetObserver(mObserver); 2093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 2103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mAdapter = adapter; 2113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mAdapter != null) { 2123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani adapter.registerDataSetObserver(mObserver); 2133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 2143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 2153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mDropDownList != null) { 2163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.setAdapter(mAdapter); 2173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 2183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 2193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 2203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 22120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Set where the optional prompt view should appear. The default is {@link 22220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * #POSITION_PROMPT_ABOVE}. 2233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 2243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param position A position constant declaring where the prompt should be displayed. 2253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #POSITION_PROMPT_ABOVE 2263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #POSITION_PROMPT_BELOW 2273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 2283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setPromptPosition(int position) { 2293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPromptPosition = position; 2303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 2313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 2323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 2333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return Where the optional prompt view should appear. 2343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #POSITION_PROMPT_ABOVE 2353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #POSITION_PROMPT_BELOW 2363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 2373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public int getPromptPosition() { 2383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mPromptPosition; 2393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 2403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 2413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 2423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Set whether this window should be modal when shown. 2433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 24420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * <p>If a popup window is modal, it will receive all touch and key input. If the user touches 24520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * outside the popup window's content area the popup window will be dismissed. 2463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 2473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param modal {@code true} if the popup window should be modal, {@code false} otherwise. 2483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 2493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setModal(boolean modal) { 2503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mModal = true; 2513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setFocusable(modal); 2523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 2533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 2543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 2553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Returns whether the popup window will be modal when shown. 2563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 2573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return {@code true} if the popup window will be modal, {@code false} otherwise. 2583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 2593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public boolean isModal() { 2603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mModal; 2613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 2623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 2633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 2643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Forces outside touches to be ignored. Normally if {@link #isDropDownAlwaysVisible()} is 26520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * false, we allow outside touch to dismiss the dropdown. If this is set to true, then we ignore 26620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * outside touch even when the drop down is not set to always visible. 2673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 2683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @hide Used only by AutoCompleteTextView to handle some internal special cases. 2693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 2703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setForceIgnoreOutsideTouch(boolean forceIgnoreOutsideTouch) { 2713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mForceIgnoreOutsideTouch = forceIgnoreOutsideTouch; 2723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 2733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 2743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 2753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Sets whether the drop-down should remain visible under certain conditions. 2763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 27720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * The drop-down will occupy the entire screen below {@link #getAnchorView} regardless of the 27820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * size or content of the list. {@link #getBackground()} will fill any space that is not used 27920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * by the list. 2803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 2813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param dropDownAlwaysVisible Whether to keep the drop-down visible. 2823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @hide Only used by AutoCompleteTextView under special conditions. 2833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 2843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) { 2853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownAlwaysVisible = dropDownAlwaysVisible; 2863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 2873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 2883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 2893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return Whether the drop-down is visible under special conditions. 2903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @hide Only used by AutoCompleteTextView under special conditions. 2913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 2923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public boolean isDropDownAlwaysVisible() { 2933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mDropDownAlwaysVisible; 2943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 2953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 2963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 2973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Sets the operating mode for the soft input area. 2983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 29920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param mode The desired mode, see {@link android.view.WindowManager.LayoutParams#softInputMode} 30020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * for the full list 3013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see android.view.WindowManager.LayoutParams#softInputMode 3023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #getSoftInputMode() 3033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 3043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setSoftInputMode(int mode) { 3053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setSoftInputMode(mode); 3063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 3073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 3083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 3093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Returns the current value in {@link #setSoftInputMode(int)}. 3103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 3113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #setSoftInputMode(int) 3123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see android.view.WindowManager.LayoutParams#softInputMode 3133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 3143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public int getSoftInputMode() { 3153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mPopup.getSoftInputMode(); 3163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 3173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 3183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 3193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Sets a drawable to use as the list item selector. 3203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 3213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param selector List selector drawable to use in the popup. 3223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 3233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setListSelector(Drawable selector) { 3243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownListHighlight = selector; 3253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 3263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 3273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 3283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return The background drawable for the popup window. 3293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 3303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public Drawable getBackground() { 3313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mPopup.getBackground(); 3323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 3333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 3343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 3353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Sets a drawable to be the background for the popup window. 3363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 3373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param d A drawable to set as the background. 3383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 3393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setBackgroundDrawable(Drawable d) { 3403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setBackgroundDrawable(d); 3413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 3423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 3433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 3443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Set an animation style to use when the popup window is shown or dismissed. 3453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 3463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param animationStyle Animation style to use. 3473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 3483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setAnimationStyle(int animationStyle) { 3493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setAnimationStyle(animationStyle); 3503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 3513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 3523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 35320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Returns the animation style that will be used when the popup window is shown or dismissed. 3543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 3553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return Animation style that will be used. 3563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 3573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public int getAnimationStyle() { 3583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mPopup.getAnimationStyle(); 3593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 3603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 3613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 3623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Returns the view that will be used to anchor this popup. 3633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 3643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return The popup's anchor view 3653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 3663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public View getAnchorView() { 3673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mDropDownAnchorView; 3683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 3693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 3703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 37120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Sets the popup's anchor view. This popup will always be positioned relative to the anchor 37220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * view when shown. 3733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 3743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param anchor The view to use as an anchor. 3753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 3763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setAnchorView(View anchor) { 3773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownAnchorView = anchor; 3783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 3793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 3803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 3813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return The horizontal offset of the popup from its anchor in pixels. 3823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 3833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public int getHorizontalOffset() { 3843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mDropDownHorizontalOffset; 3853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 3863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 3873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 3883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Set the horizontal offset of this popup from its anchor view in pixels. 3893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 3903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param offset The horizontal offset of the popup from its anchor. 3913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 3923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setHorizontalOffset(int offset) { 3933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownHorizontalOffset = offset; 3943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 3953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 3963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 3973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return The vertical offset of the popup from its anchor in pixels. 3983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 3993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public int getVerticalOffset() { 4003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (!mDropDownVerticalOffsetSet) { 4013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return 0; 4023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 4033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mDropDownVerticalOffset; 4043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 4053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 4063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 4073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Set the vertical offset of this popup from its anchor view in pixels. 4083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 4093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param offset The vertical offset of the popup from its anchor. 4103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 4113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setVerticalOffset(int offset) { 4123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownVerticalOffset = offset; 4133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownVerticalOffsetSet = true; 4143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 4153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 4163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 4173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return The width of the popup window in pixels. 4183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 4193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public int getWidth() { 4203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mDropDownWidth; 4213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 4223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 4233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 42420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Sets the width of the popup window in pixels. Can also be {@link #FILL_PARENT} or {@link 42520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * #WRAP_CONTENT}. 4263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 4273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param width Width of the popup window. 4283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 4293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setWidth(int width) { 4303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownWidth = width; 4313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 4323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 4333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 43420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Sets the width of the popup window by the size of its content. The final width may be larger 43520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * to accommodate styled window dressing. 4363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 4373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param width Desired width of content in pixels. 4383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 4393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setContentWidth(int width) { 4403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani Drawable popupBackground = mPopup.getBackground(); 4413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (popupBackground != null) { 4423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani popupBackground.getPadding(mTempRect); 4433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownWidth = mTempRect.left + mTempRect.right + width; 4443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 4453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani setWidth(width); 4463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 4473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 4483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 4493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 4503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return The height of the popup window in pixels. 4513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 4523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public int getHeight() { 4533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mDropDownHeight; 4543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 4553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 4563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 4573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Sets the height of the popup window in pixels. Can also be {@link #FILL_PARENT}. 4583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 4593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param height Height of the popup window. 4603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 4613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setHeight(int height) { 4623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownHeight = height; 4633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 4643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 4653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 4663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Sets a listener to receive events when a list item is clicked. 4673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 4683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param clickListener Listener to register 4693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see ListView#setOnItemClickListener(android.widget.AdapterView.OnItemClickListener) 4703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 4713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setOnItemClickListener(AdapterView.OnItemClickListener clickListener) { 4723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mItemClickListener = clickListener; 4733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 4743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 4753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 4763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Sets a listener to receive events when a list item is selected. 4773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 4783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param selectedListener Listener to register. 4793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see ListView#setOnItemSelectedListener(android.widget.AdapterView.OnItemSelectedListener) 4803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 4813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener selectedListener) { 4823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mItemSelectedListener = selectedListener; 4833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 4843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 4853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 4863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Set a view to act as a user prompt for this popup window. Where the prompt view will appear 4873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * is controlled by {@link #setPromptPosition(int)}. 4883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 4893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param prompt View to use as an informational prompt. 4903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 4913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setPromptView(View prompt) { 4923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani boolean showing = isShowing(); 4933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (showing) { 4943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani removePromptView(); 4953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 4963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPromptView = prompt; 4973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (showing) { 4983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani show(); 4993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 5033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Post a {@link #show()} call to the UI thread. 5043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 5053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void postShow() { 5063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mHandler.post(mShowDropDownRunnable); 5073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 51020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Show the popup list. If the list is already showing, this method will recalculate the popup's 51120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * size and position. 5123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 5133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void show() { 5143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int height = buildDropDown(); 5153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int widthSpec = 0; 5173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int heightSpec = 0; 5183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani boolean noInputMethod = isInputMethodNotNeeded(); 5203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mPopup.isShowing()) { 5223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) { 5233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // The call to PopupWindow's update method below can accept -1 for any 5243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // value you do not want to update. 5253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani widthSpec = -1; 5263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { 5273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani widthSpec = getAnchorView().getWidth(); 5283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 5293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani widthSpec = mDropDownWidth; 5303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mDropDownHeight == ViewGroup.LayoutParams.FILL_PARENT) { 5333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // The call to PopupWindow's update method below can accept -1 for any 5343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // value you do not want to update. 5353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani heightSpec = noInputMethod ? height : ViewGroup.LayoutParams.FILL_PARENT; 5363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (noInputMethod) { 5373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setWindowLayoutMode( 5383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT ? 5393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani ViewGroup.LayoutParams.FILL_PARENT : 0, 0); 5403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 5413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setWindowLayoutMode( 5423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT ? 5433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani ViewGroup.LayoutParams.FILL_PARENT : 0, 5443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani ViewGroup.LayoutParams.FILL_PARENT); 5453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { 5473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani heightSpec = height; 5483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 5493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani heightSpec = mDropDownHeight; 5503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); 5533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.update(getAnchorView(), mDropDownHorizontalOffset, 5553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownVerticalOffset, widthSpec, heightSpec); 5563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 5573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) { 5583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani widthSpec = ViewGroup.LayoutParams.FILL_PARENT; 5593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 5603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) { 5613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setWidth(getAnchorView().getWidth()); 5623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 5633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setWidth(mDropDownWidth); 5643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mDropDownHeight == ViewGroup.LayoutParams.FILL_PARENT) { 5683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani heightSpec = ViewGroup.LayoutParams.FILL_PARENT; 5693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 5703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mDropDownHeight == ViewGroup.LayoutParams.WRAP_CONTENT) { 5713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setHeight(height); 5723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 5733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setHeight(mDropDownHeight); 5743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setWindowLayoutMode(widthSpec, heightSpec); 5783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // use outside touchable to dismiss drop down when touching outside of it, so 5803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // only set this if the dropdown is not always visible 5813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); 5823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setTouchInterceptor(mTouchInterceptor); 5833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.showAsDropDown(getAnchorView(), 5843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownHorizontalOffset, mDropDownVerticalOffset); 5853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.setSelection(ListView.INVALID_POSITION); 5863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (!mModal || mDropDownList.isInTouchMode()) { 5883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani clearListSelection(); 5893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (!mModal) { 5913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mHandler.post(mHideSelector); 5923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 5953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 5963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 5973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Dismiss the popup window. 5983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 5993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void dismiss() { 6003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.dismiss(); 6013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani removePromptView(); 6023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setContentView(null); 6033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList = null; 6043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mHandler.removeCallbacks(mResizePopupRunnable); 6053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 6073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 6083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Set a listener to receive a callback when the popup is dismissed. 6093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 6103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param listener Listener that will be notified when the popup is dismissed. 6113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 6123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setOnDismissListener(PopupWindow.OnDismissListener listener) { 6133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setOnDismissListener(listener); 6143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 6163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private void removePromptView() { 6173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mPromptView != null) { 6183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final ViewParent parent = mPromptView.getParent(); 6193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (parent instanceof ViewGroup) { 6203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final ViewGroup group = (ViewGroup) parent; 6213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani group.removeView(mPromptView); 6223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 6263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 62720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Control how the popup operates with an input method: one of {@link 62820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * #INPUT_METHOD_FROM_FOCUSABLE}, {@link #INPUT_METHOD_NEEDED}, or {@link 62920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * #INPUT_METHOD_NOT_NEEDED}. 6303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 63120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * <p>If the popup is showing, calling this method will take effect only the next time the popup 63220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * is shown or through a manual call to the {@link #show()} method.</p> 6333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 6343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #getInputMethodMode() 6353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #show() 6363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 6373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setInputMethodMode(int mode) { 6383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setInputMethodMode(mode); 6393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 6413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 6423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Return the current value in {@link #setInputMethodMode(int)}. 6433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 6443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #setInputMethodMode(int) 6453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 6463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public int getInputMethodMode() { 6473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mPopup.getInputMethodMode(); 6483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 6503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 65120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Set the selected position of the list. Only valid when {@link #isShowing()} == {@code true}. 6523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 6533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param position List position to set as selected. 6543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 6553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void setSelection(int position) { 6563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani DropDownListView list = mDropDownList; 6573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (isShowing() && list != null) { 6583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani list.mListSelectionHidden = false; 6593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani list.setSelection(position); 6603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (list.getChoiceMode() != ListView.CHOICE_MODE_NONE) { 6613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani list.setItemChecked(position, true); 6623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 6663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 66720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Clear any current list selection. Only valid when {@link #isShowing()} == {@code true}. 6683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 6693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void clearListSelection() { 6703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final DropDownListView list = mDropDownList; 6713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (list != null) { 6723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // WARNING: Please read the comment where mListSelectionHidden is declared 6733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani list.mListSelectionHidden = true; 6743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani //list.hideSelector(); 6753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani list.requestLayout(); 6763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 6793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 6803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return {@code true} if the popup is currently showing, {@code false} otherwise. 6813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 6823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public boolean isShowing() { 6833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mPopup.isShowing(); 6843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 6863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 68720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return {@code true} if this popup is configured to assume the user does not need to interact 68820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * with the IME while it is showing, {@code false} otherwise. 6893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 6903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public boolean isInputMethodNotNeeded() { 6913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mPopup.getInputMethodMode() == INPUT_METHOD_NOT_NEEDED; 6923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 6933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 6943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 6953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Perform an item click operation on the specified list adapter position. 6963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 6973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param position Adapter position for performing the click 69820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return true if the click action could be performed, false if not. (e.g. if the popup was not 69920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * showing, this method would return false.) 7003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 7013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public boolean performItemClick(int position) { 7023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (isShowing()) { 7033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mItemClickListener != null) { 7043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final DropDownListView list = mDropDownList; 7053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final View child = list.getChildAt(position - list.getFirstVisiblePosition()); 7063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final ListAdapter adapter = list.getAdapter(); 7073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mItemClickListener.onItemClick(list, child, position, adapter.getItemId(position)); 7083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return true; 7103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return false; 7123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 7143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 7153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return The currently selected item or null if the popup is not showing. 7163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 7173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public Object getSelectedItem() { 7183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (!isShowing()) { 7193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return null; 7203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mDropDownList.getSelectedItem(); 7223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 7243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 72520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return The position of the currently selected item or {@link ListView#INVALID_POSITION} if 72620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * {@link #isShowing()} == {@code false}. 7273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see ListView#getSelectedItemPosition() 7283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 7293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public int getSelectedItemPosition() { 7303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (!isShowing()) { 7313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return ListView.INVALID_POSITION; 7323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mDropDownList.getSelectedItemPosition(); 7343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 7363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 73720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return The ID of the currently selected item or {@link ListView#INVALID_ROW_ID} if {@link 73820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * #isShowing()} == {@code false}. 7393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see ListView#getSelectedItemId() 7403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 7413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public long getSelectedItemId() { 7423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (!isShowing()) { 7433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return ListView.INVALID_ROW_ID; 7443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mDropDownList.getSelectedItemId(); 7463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 7483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 74920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return The View for the currently selected item or null if {@link #isShowing()} == {@code 75020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * false}. 7513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see ListView#getSelectedView() 7523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 7533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public View getSelectedView() { 7543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (!isShowing()) { 7553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return null; 7563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mDropDownList.getSelectedView(); 7583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 7603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 76120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return The {@link ListView} displayed within the popup window. Only valid when {@link 76220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * #isShowing()} == {@code true}. 7633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 7643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public ListView getListView() { 7653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mDropDownList; 7663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 7683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 76920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * The maximum number of list items that can be visible and still have the list expand when 77020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * touched. 7713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 7723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param max Max number of items that can be visible and still allow the list to expand. 7733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 7743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani void setListItemExpandMax(int max) { 7753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mListItemExpandMaximum = max; 7763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 7773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 7783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 77920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Filter key down events. By forwarding key down events to this function, views using non-modal 78020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * ListPopupWindow can have it handle key selection of items. 7813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 7823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param keyCode keyCode param passed to the host view's onKeyDown 78320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param event event param passed to the host view's onKeyDown 7843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return true if the event was handled, false if it was ignored. 7853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #setModal(boolean) 7863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 7873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public boolean onKeyDown(int keyCode, KeyEvent event) { 7883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // when the drop down is shown, we drive it directly 7893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (isShowing()) { 7903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // the key events are forwarded to the list in the drop down view 7913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // note that ListView handles space but we don't want that to happen 7923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // also if selection is not currently in the drop down, then don't 7933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // let center or enter presses go there since that would cause it 7943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // to select one of its items 7953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (keyCode != KeyEvent.KEYCODE_SPACE 7963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani && (mDropDownList.getSelectedItemPosition() >= 0 7973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani || (keyCode != KeyEvent.KEYCODE_ENTER 7983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani && keyCode != KeyEvent.KEYCODE_DPAD_CENTER))) { 7993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int curIndex = mDropDownList.getSelectedItemPosition(); 8003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani boolean consumed; 8013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 8023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final boolean below = !mPopup.isAboveAnchor(); 8033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 8043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final ListAdapter adapter = mAdapter; 8053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 8063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani boolean allEnabled; 8073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int firstItem = Integer.MAX_VALUE; 8083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int lastItem = Integer.MIN_VALUE; 8093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 8103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (adapter != null) { 8113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani allEnabled = adapter.areAllItemsEnabled(); 8123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani firstItem = allEnabled ? 0 : 813ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns mDropDownList.lookForSelectablePosition(0, true); 8143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani lastItem = allEnabled ? adapter.getCount() - 1 : 815ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns mDropDownList.lookForSelectablePosition(adapter.getCount() - 1, false); 8163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 8173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 8183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if ((below && keyCode == KeyEvent.KEYCODE_DPAD_UP && curIndex <= firstItem) || 8193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani (!below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN && curIndex >= lastItem)) { 8203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // When the selection is at the top, we block the key 8213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // event to prevent focus from moving. 8223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani clearListSelection(); 8233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 8243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani show(); 8253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return true; 8263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 8273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // WARNING: Please read the comment where mListSelectionHidden 8283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // is declared 8293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.mListSelectionHidden = false; 8303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 8313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 8323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani consumed = mDropDownList.onKeyDown(keyCode, event); 83320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (DEBUG) { 83420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns Log.v(TAG, "Key down: code=" + keyCode + " list consumed=" + consumed); 83520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 8363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 8373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (consumed) { 8383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // If it handled the key event, then the user is 8393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // navigating in the list, so we should put it in front. 8403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 8413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // Here's a little trick we need to do to make sure that 8423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // the list view is actually showing its focus indicator, 8433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // by ensuring it has focus and getting its window out 8443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // of touch mode. 8453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.requestFocusFromTouch(); 8463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani show(); 8473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 8483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani switch (keyCode) { 8493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // avoid passing the focus from the text view to the 8503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // next component 8513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani case KeyEvent.KEYCODE_ENTER: 8523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani case KeyEvent.KEYCODE_DPAD_CENTER: 8533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani case KeyEvent.KEYCODE_DPAD_DOWN: 8543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani case KeyEvent.KEYCODE_DPAD_UP: 8553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return true; 8563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 8573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 8583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { 8593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // when the selection is at the bottom, we block the 8603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // event to avoid going to the next focusable widget 8613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (curIndex == lastItem) { 8623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return true; 8633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 8643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else if (!below && keyCode == KeyEvent.KEYCODE_DPAD_UP && 8653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani curIndex == firstItem) { 8663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return true; 8673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 8683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 8693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 8703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 8713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 8723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return false; 8733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 8743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 8753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 87620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Filter key down events. By forwarding key up events to this function, views using non-modal 87720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * ListPopupWindow can have it handle key selection of items. 8783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 8793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param keyCode keyCode param passed to the host view's onKeyUp 88020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param event event param passed to the host view's onKeyUp 8813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return true if the event was handled, false if it was ignored. 8823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @see #setModal(boolean) 8833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 8843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public boolean onKeyUp(int keyCode, KeyEvent event) { 8853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (isShowing() && mDropDownList.getSelectedItemPosition() >= 0) { 8863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani boolean consumed = mDropDownList.onKeyUp(keyCode, event); 8873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (consumed) { 8883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani switch (keyCode) { 8893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // if the list accepts the key events and the key event 8903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // was a click, the text view gets the selected item 8913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // from the drop down as its content 8923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani case KeyEvent.KEYCODE_ENTER: 8933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani case KeyEvent.KEYCODE_DPAD_CENTER: 8943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani dismiss(); 8953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani break; 8963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 8973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 8983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return consumed; 8993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 9003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return false; 9013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 9023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 90420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * <p>Builds the popup window's content and returns the height the popup should have. Returns -1 90520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * when the content already exists.</p> 9063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 9073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return the content's height or -1 if content already exists 9083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 9093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private int buildDropDown() { 9103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani ViewGroup dropDownView; 9113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int otherHeights = 0; 9123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mDropDownList == null) { 9143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani Context context = mContext; 9153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 9173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * This Runnable exists for the sole purpose of checking if the view layout has got 9183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * completed and if so call showDropDown to display the drop down. This is used to show 9193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * the drop down as soon as possible after user opens up the search dialog, without 9203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * waiting for the normal UI pipeline to do it's job which is slower than this method. 9213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 9223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mShowDropDownRunnable = new Runnable() { 9233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void run() { 9243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // View layout should be all done before displaying the drop down. 9253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani View view = getAnchorView(); 9263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (view != null && view.getWindowToken() != null) { 9273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani show(); 9283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 9293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 9303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani }; 9313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList = new DropDownListView(context, !mModal); 9333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mDropDownListHighlight != null) { 9343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.setSelector(mDropDownListHighlight); 9353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 9363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.setAdapter(mAdapter); 9373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.setOnItemClickListener(mItemClickListener); 9383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.setFocusable(true); 9393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.setFocusableInTouchMode(true); 9403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 9413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void onItemSelected(AdapterView<?> parent, View view, 94220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int position, long id) { 9433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (position != -1) { 9453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani DropDownListView dropDownList = mDropDownList; 9463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (dropDownList != null) { 9483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani dropDownList.mListSelectionHidden = false; 9493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 9503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 9513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 9523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void onNothingSelected(AdapterView<?> parent) { 9543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 9553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani }); 9563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.setOnScrollListener(mScrollListener); 9573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mItemSelectedListener != null) { 9593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.setOnItemSelectedListener(mItemSelectedListener); 9603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 9613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani dropDownView = mDropDownList; 9633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani View hintView = mPromptView; 9653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (hintView != null) { 9663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // if a hint has been specified, we accomodate more space for it and 9673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // add a text view in the drop down menu, at the bottom of the list 9683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani LinearLayout hintContainer = new LinearLayout(context); 9693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani hintContainer.setOrientation(LinearLayout.VERTICAL); 9703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani LinearLayout.LayoutParams hintParams = new LinearLayout.LayoutParams( 9723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani ViewGroup.LayoutParams.FILL_PARENT, 0, 1.0f 9733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani ); 9743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani switch (mPromptPosition) { 9763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani case POSITION_PROMPT_BELOW: 9773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani hintContainer.addView(dropDownView, hintParams); 9783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani hintContainer.addView(hintView); 9793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani break; 9803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani case POSITION_PROMPT_ABOVE: 9823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani hintContainer.addView(hintView); 9833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani hintContainer.addView(dropDownView, hintParams); 9843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani break; 9853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani default: 9873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani Log.e(TAG, "Invalid hint position " + mPromptPosition); 9883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani break; 9893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 9903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // measure the hint's height to find how much more vertical space 9923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // we need to add to the drop down's height 9933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int widthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.AT_MOST); 9943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int heightSpec = MeasureSpec.UNSPECIFIED; 9953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani hintView.measure(widthSpec, heightSpec); 9963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 9973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani hintParams = (LinearLayout.LayoutParams) hintView.getLayoutParams(); 9983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani otherHeights = hintView.getMeasuredHeight() + hintParams.topMargin 9993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani + hintParams.bottomMargin; 10003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 10013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani dropDownView = hintContainer; 10023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 10033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 10043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setContentView(dropDownView); 10053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 10063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani dropDownView = (ViewGroup) mPopup.getContentView(); 10073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final View view = mPromptView; 10083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (view != null) { 10093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani LinearLayout.LayoutParams hintParams = 10103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani (LinearLayout.LayoutParams) view.getLayoutParams(); 10113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani otherHeights = view.getMeasuredHeight() + hintParams.topMargin 10123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani + hintParams.bottomMargin; 10133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 10143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 10153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 10163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // getMaxAvailableHeight() subtracts the padding, so we put it back 10173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // to get the available height for the whole window 10183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int padding = 0; 10193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani Drawable background = mPopup.getBackground(); 10203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (background != null) { 10213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani background.getPadding(mTempRect); 10223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani padding = mTempRect.top + mTempRect.bottom; 10233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 10243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // If we don't have an explicit vertical offset, determine one from the window 10253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // background so that content will line up. 10263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (!mDropDownVerticalOffsetSet) { 10273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownVerticalOffset = -mTempRect.top; 10283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 10293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 10303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mTempRect.setEmpty(); 10313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 10323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 10333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // Max height available on the screen for a popup. 10343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani boolean ignoreBottomDecorations = 10353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED; 10363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final int maxHeight = getMaxAvailableHeight( 1037ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns getAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations); 10383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 10393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mDropDownAlwaysVisible || mDropDownHeight == ViewGroup.LayoutParams.FILL_PARENT) { 10403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return maxHeight + padding; 10413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 10423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 10433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final int childWidthSpec; 10443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani switch (mDropDownWidth) { 10453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani case ViewGroup.LayoutParams.WRAP_CONTENT: 10463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani childWidthSpec = MeasureSpec.makeMeasureSpec( 10473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mContext.getResources().getDisplayMetrics().widthPixels - 10483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani (mTempRect.left + mTempRect.right), 10493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani MeasureSpec.AT_MOST); 10503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani break; 10513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani case ViewGroup.LayoutParams.FILL_PARENT: 10523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani childWidthSpec = MeasureSpec.makeMeasureSpec( 10533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mContext.getResources().getDisplayMetrics().widthPixels - 10543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani (mTempRect.left + mTempRect.right), 10553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani MeasureSpec.EXACTLY); 10563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani break; 10573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani default: 10583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani childWidthSpec = MeasureSpec.makeMeasureSpec(mDropDownWidth, MeasureSpec.EXACTLY); 10593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani break; 10603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 1061ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns 106279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final int listContent = mDropDownList.measureHeightOfChildrenCompat(childWidthSpec, 10633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 0, DropDownListView.NO_POSITION, maxHeight - otherHeights, -1); 10643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // add padding only if the list has items in it, that way we don't show 10653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // the popup if it is not needed 106620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns if (listContent > 0) { 106720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns otherHeights += padding; 106820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns } 10693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 10703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return listContent + otherHeights; 10713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 10723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 10733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 10743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Copied from PopupWindow.java of JB 10753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 107620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Returns the maximum height that is available for the popup to be completely shown, optionally 107720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * ignoring any bottom decorations such as the input method. It is recommended that this height 107820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * be the maximum for the popup's height, otherwise it is possible that the popup will be 10793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * clipped. 10803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 108120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param anchor The view on which the popup window must be anchored. 108220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param yOffset y offset from the view's bottom edge 108320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param ignoreBottomDecorations if true, the height returned will be all the way to the bottom 108420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * of the display, ignoring any bottom decorations 108520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @return The maximum available height for the popup to be completely shown. 10863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @hide Pending API council approval. 10873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 10883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) { 10893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final Rect displayFrame = new Rect(); 10903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani anchor.getWindowVisibleDisplayFrame(displayFrame); 10913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 10923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int[] mDrawingLocation = new int[2]; 10933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final int[] anchorPos = mDrawingLocation; 10943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani anchor.getLocationOnScreen(anchorPos); 10953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 10963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int bottomEdge = displayFrame.bottom; 10973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (ignoreBottomDecorations) { 10983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani Resources res = anchor.getContext().getResources(); 10993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani bottomEdge = res.getDisplayMetrics().heightPixels; 11003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 11013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset; 11023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset; 11033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 11043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // anchorPos[1] is distance from anchor to top of screen 11053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani int returnedHeight = Math.max(distanceToBottom, distanceToTop); 11063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mPopup.getBackground() != null) { 11073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.getBackground().getPadding(mTempRect); 11083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani returnedHeight -= mTempRect.top + mTempRect.bottom; 11093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 11103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 11113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return returnedHeight; 11123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 11133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 11143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 111520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * <p>Wrapper class for a ListView. This wrapper can hijack the focus to make sure the list uses 111620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * the appropriate drawables and states when displayed on screen within a drop down. The focus 111720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * is never actually passed to the drop down in this mode; the list only looks focused.</p> 11183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 11193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private static class DropDownListView extends ListView { 112020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 11213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private static final String TAG = ListPopupWindow.TAG + ".DropDownListView"; 112220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 11233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /* 112420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * WARNING: This is a workaround for a touch mode issue. 112520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 112620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Touch mode is propagated lazily to windows. This causes problems in 112720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * the following scenario: 112820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * - Type something in the AutoCompleteTextView and get some results 112920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * - Move down with the d-pad to select an item in the list 113020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * - Move up with the d-pad until the selection disappears 113120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * - Type more text in the AutoCompleteTextView *using the soft keyboard* 113220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * and get new results; you are now in touch mode 113320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * - The selection comes back on the first item in the list, even though 113420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * the list is supposed to be in touch mode 113520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 113620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Using the soft keyboard triggers the touch mode change but that change 113720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * is propagated to our window only after the first list layout, therefore 113820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * after the list attempts to resurrect the selection. 113920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 114020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * The trick to work around this issue is to pretend the list is in touch 114120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * mode when we know that the selection should not appear, that is when 114220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * we know the user moved the selection away from the list. 114320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 114420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * This boolean is set to true whenever we explicitly hide the list's 114520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * selection and reset to false whenever we know the user moved the 114620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * selection back to the list. 114720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * 114820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * When this boolean is true, isInTouchMode() returns true, otherwise it 114920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * returns super.isInTouchMode(). 115020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns */ 11513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private boolean mListSelectionHidden; 11523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 11533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 11543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public static final int INVALID_POSITION = -1; 115520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 11563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani static final int NO_POSITION = -1; 11573565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 11583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 11593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 11603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * True if this wrapper should fake focus. 11613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 11623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private boolean mHijackFocus; 11633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 11643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 11653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * <p>Creates a new list view wrapper.</p> 11663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 11673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param context this view's context 11683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 11693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public DropDownListView(Context context, boolean hijackFocus) { 11703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani super(context, null, R.attr.dropDownListViewStyle); 11713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mHijackFocus = hijackFocus; 11723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani setCacheColorHint(0); // Transparent, since the background drawable could be anything. 11733565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 11743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 11753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 11763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * Find a position that can be selected (i.e., is not a separator). 11773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 11783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param position The starting position to look at. 11793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @param lookDown Whether to look down for other positions. 11803565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return The next selectable position starting at position and then searching either up or 11813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * down. Returns {@link #INVALID_POSITION} if nothing can be found. 11823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 1183e6072e2d918169bd827cf7431347fb648124c227Jeff Brown private int lookForSelectablePosition(int position, boolean lookDown) { 11843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final ListAdapter adapter = getAdapter(); 11853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (adapter == null || isInTouchMode()) { 11863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return INVALID_POSITION; 11873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 11883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 11893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final int count = adapter.getCount(); 11903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (!getAdapter().areAllItemsEnabled()) { 11913565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (lookDown) { 11923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani position = Math.max(0, position); 11933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani while (position < count && !adapter.isEnabled(position)) { 11943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani position++; 11953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 11963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 11973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani position = Math.min(position, count - 1); 11983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani while (position >= 0 && !adapter.isEnabled(position)) { 11993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani position--; 12003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 12013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 12023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 12033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (position < 0 || position >= count) { 12043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return INVALID_POSITION; 12053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 12063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return position; 12073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else { 12083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (position < 0 || position >= count) { 12093565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return INVALID_POSITION; 12103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 12113565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return position; 12123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 12133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 12143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 12153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani @Override 12163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public boolean isInTouchMode() { 12173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // WARNING: Please read the comment where mListSelectionHidden is declared 12183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return (mHijackFocus && mListSelectionHidden) || super.isInTouchMode(); 12193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 12203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 12213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 12223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * <p>Returns the focus state in the drop down.</p> 12233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 12243565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return true always if hijacking focus 12253565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 12263565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani @Override 12273565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public boolean hasWindowFocus() { 12283565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mHijackFocus || super.hasWindowFocus(); 12293565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 12303565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 12313565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 12323565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * <p>Returns the focus state in the drop down.</p> 12333565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 12343565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return true always if hijacking focus 12353565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 12363565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani @Override 12373565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public boolean isFocused() { 12383565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mHijackFocus || super.isFocused(); 12393565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 12403565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 12413565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 12423565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * <p>Returns the focus state in the drop down.</p> 12433565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 12443565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return true always if hijacking focus 12453565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 12463565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani @Override 12473565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public boolean hasFocus() { 12483565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return mHijackFocus || super.hasFocus(); 12493565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 12503565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 12513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani /** 125220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * Measures the height of the given range of children (inclusive) and returns the height 125320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * with this ListView's padding and divider heights included. If maxHeight is provided, the 125420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * measuring will stop when the current height reaches maxHeight. 12553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * 125620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param widthMeasureSpec The width measure spec to be given to a child's 125720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * {@link View#measure(int, int)}. 125820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param startPosition The position of the first child to be shown. 125920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param endPosition The (inclusive) position of the last child to be 126020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * shown. Specify {@link #NO_POSITION} if the last child 126120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * should be the last available child from the adapter. 126220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param maxHeight The maximum height that will be returned (if all the 126320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * children don't fit in this value, this value will be 126420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * returned). 126520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * @param disallowPartialChildPosition In general, whether the returned height should only 126620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * contain entire children. This is more powerful--it is 126720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * the first inclusive position at which partial 126820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * children will not be allowed. Example: it looks nice 126920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * to have at least 3 completely visible children, and 127020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * in portrait this will most likely fit; but in 127120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * landscape there could be times when even 2 children 127220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * can not be completely shown, so a value of 2 127320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * (remember, inclusive) would be good (assuming 127420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns * startPosition is 0). 12753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani * @return The height of this ListView with the given children. 12763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani */ 127779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final int measureHeightOfChildrenCompat(int widthMeasureSpec, int startPosition, 127820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int endPosition, final int maxHeight, 127920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int disallowPartialChildPosition) { 1280ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns 1281ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns final int paddingTop = getListPaddingTop(); 1282ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns final int paddingBottom = getListPaddingBottom(); 1283ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns final int paddingLeft = getListPaddingLeft(); 1284ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns final int paddingRight = getListPaddingRight(); 1285ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns final int reportedDividerHeight = getDividerHeight(); 1286ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns final Drawable divider = getDivider(); 12873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 12883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final ListAdapter adapter = getAdapter(); 12893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 12903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (adapter == null) { 1291ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns return paddingTop + paddingBottom; 12923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 12933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 12943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // Include the padding of the list 1295ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns int returnedHeight = paddingTop + paddingBottom; 129620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns final int dividerHeight = ((reportedDividerHeight > 0) && divider != null) 129720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ? reportedDividerHeight : 0; 1298ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns 1299ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns // The previous height value that was less than maxHeight and contained 1300ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns // no partial children 1301ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns int prevHeightWithoutPartialChild = 0; 1302ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns 1303ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns View child = null; 1304ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns int viewType = 0; 1305ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns int count = adapter.getCount(); 1306ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns for (int i = 0; i < count; i++) { 1307ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns int newType = adapter.getItemViewType(i); 1308ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns if (newType != viewType) { 1309ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns child = null; 1310ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns viewType = newType; 1311ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns } 131220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns child = adapter.getView(i, child, this); 131320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns ; 1314ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns 1315ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns // Compute child height spec 1316ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns int heightMeasureSpec; 1317ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns int childHeight = child.getLayoutParams().height; 1318ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns if (childHeight > 0) { 131920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns heightMeasureSpec = MeasureSpec 132020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns .makeMeasureSpec(childHeight, MeasureSpec.EXACTLY); 1321ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns } else { 1322ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 1323ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns } 1324ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns child.measure(widthMeasureSpec, heightMeasureSpec); 1325ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns 1326ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns if (i > 0) { 1327ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns // Count the divider for all but one child 1328ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns returnedHeight += dividerHeight; 1329ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns } 1330ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns 1331ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns returnedHeight += child.getMeasuredHeight(); 1332ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns 1333ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns if (returnedHeight >= maxHeight) { 133420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // We went over, figure out which height to return. If returnedHeight > 133520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns // maxHeight, then the i'th position did not fit completely. 1336ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns return (disallowPartialChildPosition >= 0) // Disallowing is enabled (> -1) 1337ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns && (i > disallowPartialChildPosition) // We've past the min pos 1338ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns && (prevHeightWithoutPartialChild > 0) // We have a prev height 1339ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns && (returnedHeight != maxHeight) // i'th child did not fit completely 1340ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns ? prevHeightWithoutPartialChild 1341ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns : maxHeight; 1342ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns } 1343ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns 1344ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns if ((disallowPartialChildPosition >= 0) && (i >= disallowPartialChildPosition)) { 1345ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns prevHeightWithoutPartialChild = returnedHeight; 1346ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns } 1347ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns } 1348ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns 1349ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns // At this point, we went through the range of children, and they each 1350ba2e44b17a9ed3d39d05b52f9764165e063f5386Trevor Johns // completely fit, so return the returnedHeight 13513565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return returnedHeight; 13523565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 13533565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 13543565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 13553565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 13563565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private class PopupDataSetObserver extends DataSetObserver { 135720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 13583565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani @Override 13593565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void onChanged() { 13603565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (isShowing()) { 13613565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani // Resize the popup to fit new content 13623565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani show(); 13633565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 13643565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 13653565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 13663565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani @Override 13673565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void onInvalidated() { 13683565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani dismiss(); 13693565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 13703565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 13713565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 13723565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private class ListSelectorHider implements Runnable { 137320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 13743565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void run() { 13753565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani clearListSelection(); 13763565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 13773565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 13783565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 13793565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private class ResizePopupRunnable implements Runnable { 138020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 13813565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void run() { 13823565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (mDropDownList != null && mDropDownList.getCount() > mDropDownList.getChildCount() && 13833565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mDropDownList.getChildCount() <= mListItemExpandMaximum) { 13843565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 13853565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani show(); 13863565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 13873565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 13883565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 13893565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 13903565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private class PopupTouchInterceptor implements OnTouchListener { 139120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 13923565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public boolean onTouch(View v, MotionEvent event) { 13933565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final int action = event.getAction(); 13943565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final int x = (int) event.getX(); 13953565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani final int y = (int) event.getY(); 13963565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 13973565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (action == MotionEvent.ACTION_DOWN && 13983565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mPopup != null && mPopup.isShowing() && 13993565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani (x >= 0 && x < mPopup.getWidth() && y >= 0 && y < mPopup.getHeight())) { 14003565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mHandler.postDelayed(mResizePopupRunnable, EXPAND_LIST_TIMEOUT); 14013565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } else if (action == MotionEvent.ACTION_UP) { 14023565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mHandler.removeCallbacks(mResizePopupRunnable); 14033565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 14043565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani return false; 14053565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 14063565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 14073565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 14083565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani private class PopupScrollListener implements ListView.OnScrollListener { 140920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns 14103565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, 141120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns int totalItemCount) { 14123565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 14133565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 14143565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani 14153565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani public void onScrollStateChanged(AbsListView view, int scrollState) { 14163565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani if (scrollState == SCROLL_STATE_TOUCH_SCROLL && 14173565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani !isInputMethodNotNeeded() && mPopup.getContentView() != null) { 14183565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mHandler.removeCallbacks(mResizePopupRunnable); 14193565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani mResizePopupRunnable.run(); 14203565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 14213565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 14223565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani } 14233565bf7048dfa3c5b5593d0df2259bd856f3b987Anirudh Dewani}