SpinnerICS.java revision 449ba8fe7056873134b0ee02ad5acb615bc7d249
1da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownpackage android.support.v7.internal.widget;
279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes/*
479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Copyright (C) 2007 The Android Open Source Project
579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes *
679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Licensed under the Apache License, Version 2.0 (the "License");
779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * you may not use this file except in compliance with the License.
879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * You may obtain a copy of the License at
979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes *
1079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes *      http://www.apache.org/licenses/LICENSE-2.0
1179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes *
1279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Unless required by applicable law or agreed to in writing, software
1379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * distributed under the License is distributed on an "AS IS" BASIS,
1479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * See the License for the specific language governing permissions and
1679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * limitations under the License.
1779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */
1879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
1979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.app.AlertDialog;
2079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.content.Context;
2179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.content.DialogInterface;
2279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.content.DialogInterface.OnClickListener;
2379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.content.res.TypedArray;
2479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.database.DataSetObserver;
2579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.graphics.Rect;
2679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.graphics.drawable.Drawable;
27da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.appcompat.R;
2879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.util.AttributeSet;
2979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.view.Gravity;
3079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.view.View;
3179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.view.ViewGroup;
3279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.widget.AdapterView;
3379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.widget.ListAdapter;
3479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.widget.ListView;
3579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.widget.Spinner;
3679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.widget.SpinnerAdapter;
3779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
3879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
3979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes/**
4079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * A view that displays one child at a time and lets the user pick among them.
4179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The items in the Spinner come from the {@link android.widget.Adapter} associated with
4279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * this view.
4379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes *
4479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-spinner.html">Spinner
4579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * tutorial</a>.</p>
4679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes *
4779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @attr ref R.styleable#Spinner_prompt
4879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */
4979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesclass SpinnerICS extends AbsSpinnerICS implements OnClickListener {
5079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    private static final String TAG = "Spinner";
5179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
5279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    // Only measure this many items to get a decent max width.
5379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    private static final int MAX_ITEMS_MEASURED = 15;
5479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
5579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
5679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Use a dialog window for selecting spinner options.
5779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
5879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    static final int MODE_DIALOG = 0;
5979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
6079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
6179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Use a dropdown anchored to the Spinner for selecting spinner options.
6279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
6379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    static final int MODE_DROPDOWN = 1;
6479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
6579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
6679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Use the theme-supplied value to select the dropdown mode.
6779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
6879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    private static final int MODE_THEME = -1;
6979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
7079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    private SpinnerPopup mPopup;
7179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    private DropDownAdapter mTempAdapter;
7279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    int mDropDownWidth;
7379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
7479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    private int mGravity;
7579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
7679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    private Rect mTempRect = new Rect();
7779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
7879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
7979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Construct a new spinner with the given context's theme.
8079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
8179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param context The Context the view is running in, through which it can
8279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *        access the current theme, resources, etc.
8379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
8479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    SpinnerICS(Context context) {
8579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        this(context, null);
8679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
8779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
8879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
8979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Construct a new spinner with the given context's theme and the supplied
9079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * mode of displaying choices. <code>mode</code> may be one of
9179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * {@link #MODE_DIALOG} or {@link #MODE_DROPDOWN}.
9279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
9379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param context The Context the view is running in, through which it can
9479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *        access the current theme, resources, etc.
9579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param mode Constant describing how the user will select choices from the spinner.
9679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
9779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @see #MODE_DIALOG
9879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @see #MODE_DROPDOWN
9979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
10079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    SpinnerICS(Context context, int mode) {
10179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        this(context, null, R.attr.spinnerStyle, mode);
10279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
10379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
10479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
10579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Construct a new spinner with the given context's theme and the supplied attribute set.
10679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
10779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param context The Context the view is running in, through which it can
10879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *        access the current theme, resources, etc.
10979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param attrs The attributes of the XML tag that is inflating the view.
11079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
11179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    SpinnerICS(Context context, AttributeSet attrs) {
11279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        this(context, attrs, R.attr.spinnerStyle);
11379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
11479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
11579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
11679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Construct a new spinner with the given context's theme, the supplied attribute set,
11779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * and default style.
11879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
11979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param context The Context the view is running in, through which it can
12079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *        access the current theme, resources, etc.
12179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param attrs The attributes of the XML tag that is inflating the view.
12279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param defStyle The default style to apply to this view. If 0, no style
12379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *        will be applied (beyond what is included in the theme). This may
12479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *        either be an attribute resource, whose value will be retrieved
12579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *        from the current theme, or an explicit style resource.
12679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
12779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    SpinnerICS(Context context, AttributeSet attrs, int defStyle) {
12879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        this(context, attrs, defStyle, MODE_THEME);
12979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
13079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
13179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
13279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Construct a new spinner with the given context's theme, the supplied attribute set,
13379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * and default style. <code>mode</code> may be one of {@link #MODE_DIALOG} or
13479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * {@link #MODE_DROPDOWN} and determines how the user will select choices from the spinner.
13579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
13679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param context The Context the view is running in, through which it can
13779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *        access the current theme, resources, etc.
13879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param attrs The attributes of the XML tag that is inflating the view.
13979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param defStyle The default style to apply to this view. If 0, no style
14079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *        will be applied (beyond what is included in the theme). This may
14179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *        either be an attribute resource, whose value will be retrieved
14279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *        from the current theme, or an explicit style resource.
14379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param mode Constant describing how the user will select choices from the spinner.
14479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
14579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @see #MODE_DIALOG
14679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @see #MODE_DROPDOWN
14779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
14879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    SpinnerICS(Context context, AttributeSet attrs, int defStyle, int mode) {
14979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        super(context, attrs, defStyle);
15079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
15179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        TypedArray a = context.obtainStyledAttributes(attrs,
15279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                R.styleable.Spinner, defStyle, 0);
15379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
15479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (mode == MODE_THEME) {
15579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mode = a.getInt(R.styleable.Spinner_spinnerMode, MODE_DIALOG);
15679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
15779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
15879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        switch (mode) {
15979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            case MODE_DIALOG: {
16079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                mPopup = new DialogPopup();
16179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                break;
16279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
16379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
16479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            case MODE_DROPDOWN: {
16579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                DropdownPopup popup = new DropdownPopup(context, attrs, defStyle);
16679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
16779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                mDropDownWidth = a.getLayoutDimension(R.styleable.Spinner_android_dropDownWidth,
16879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                        ViewGroup.LayoutParams.WRAP_CONTENT);
16979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
17079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                popup.setBackgroundDrawable(
17179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                        a.getDrawable(R.styleable.Spinner_android_popupBackground));
17279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
17379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                final int verticalOffset = a.getDimensionPixelOffset(
17479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                        R.styleable.Spinner_android_dropDownVerticalOffset, 0);
17579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                if (verticalOffset != 0) {
17679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                    popup.setVerticalOffset(verticalOffset);
17779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                }
17879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
17979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                final int horizontalOffset = a.getDimensionPixelOffset(
18079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                        R.styleable.Spinner_android_dropDownHorizontalOffset, 0);
18179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                if (horizontalOffset != 0) {
18279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                    popup.setHorizontalOffset(horizontalOffset);
18379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                }
18479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
18579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                mPopup = popup;
18679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                break;
18779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
18879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
18979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
19079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        mGravity = a.getInt(R.styleable.Spinner_android_gravity, Gravity.CENTER);
19179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
19279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        mPopup.setPromptText(a.getString(R.styleable.Spinner_prompt));
19379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
19479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        a.recycle();
19579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
19679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Base constructor can call setAdapter before we initialize mPopup.
19779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Finish setting things up if this happened.
19879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (mTempAdapter != null) {
19979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mPopup.setAdapter(mTempAdapter);
20079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mTempAdapter = null;
20179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
20279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
20379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
20479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
20579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Describes how the selected item view is positioned. Currently only the horizontal component
20679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * is used. The default is determined by the current theme.
20779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
20879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param gravity See {@link android.view.Gravity}
20979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
21079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @attr ref android.R.styleable#Spinner_gravity
21179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
21279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    public void setGravity(int gravity) {
21379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (mGravity != gravity) {
21479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) {
21579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                gravity |= Gravity.LEFT;
21679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
21779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mGravity = gravity;
21879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            requestLayout();
21979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
22079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
22179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
22279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    @Override
22379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    public void setAdapter(SpinnerAdapter adapter) {
22479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        super.setAdapter(adapter);
22579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
22679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (mPopup != null) {
22779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mPopup.setAdapter(new DropDownAdapter(adapter));
22879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        } else {
22979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mTempAdapter = new DropDownAdapter(adapter);
23079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
23179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
23279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
23379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    @Override
23479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    public int getBaseline() {
23579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        View child = null;
23679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
23779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (getChildCount() > 0) {
23879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            child = getChildAt(0);
23979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        } else if (mAdapter != null && mAdapter.getCount() > 0) {
24079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            child = makeAndAddView(0);
24179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mRecycler.put(0, child);
24279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            removeAllViewsInLayout();
24379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
24479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
24579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (child != null) {
24679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            final int childBaseline = child.getBaseline();
24779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return childBaseline >= 0 ? child.getTop() + childBaseline : -1;
24879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        } else {
24979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return -1;
25079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
25179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
25279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
25379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    @Override
25479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    protected void onDetachedFromWindow() {
25579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        super.onDetachedFromWindow();
25679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
25779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (mPopup != null && mPopup.isShowing()) {
25879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mPopup.dismiss();
25979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
26079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
26179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
26279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
26379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * <p>A spinner does not support item click events. Calling this method
26479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * will raise an exception.</p>
26579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
26679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param l this listener will be ignored
26779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
26879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    @Override
26979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    public void setOnItemClickListener(OnItemClickListener l) {
27079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        throw new RuntimeException("setOnItemClickListener cannot be used with a spinner.");
27179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
27279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
273449ba8fe7056873134b0ee02ad5acb615bc7d249Chris Banes    void setOnItemClickListenerInt(OnItemClickListener l) {
274449ba8fe7056873134b0ee02ad5acb615bc7d249Chris Banes        super.setOnItemClickListener(l);
275449ba8fe7056873134b0ee02ad5acb615bc7d249Chris Banes    }
276449ba8fe7056873134b0ee02ad5acb615bc7d249Chris Banes
27779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    @Override
27879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
27979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
28079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (mPopup != null && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST) {
28179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            final int measuredWidth = getMeasuredWidth();
28279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            setMeasuredDimension(Math.min(Math.max(measuredWidth,
28379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                    measureContentWidth(getAdapter(), getBackground())),
28479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                    MeasureSpec.getSize(widthMeasureSpec)),
28579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                    getMeasuredHeight());
28679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
28779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
28879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
28979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
29079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @see android.view.View#onLayout(boolean,int,int,int,int)
29179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
29279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Creates and positions all views
29379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
29479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
29579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    @Override
29679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    protected void onLayout(boolean changed, int l, int t, int r, int b) {
29779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        super.onLayout(changed, l, t, r, b);
29879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        mInLayout = true;
29979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        layout(0, false);
30079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        mInLayout = false;
30179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
30279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
30379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
30479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Creates and positions all views for this Spinner.
30579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
30679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param delta Change in the selected position. +1 moves selection is moving to the right,
30779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * so views are scrolling to the left. -1 means selection is moving to the left.
30879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
30979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    @Override
31079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    void layout(int delta, boolean animate) {
31179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int childrenLeft = mSpinnerPadding.left;
31279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int childrenWidth = getRight() - getLeft() - mSpinnerPadding.left - mSpinnerPadding.right;
31379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
31479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (mDataChanged) {
31579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            handleDataChanged();
31679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
31779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
31879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Handle the empty set by removing all views
31979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (mItemCount == 0) {
32079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            resetList();
32179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return;
32279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
32379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
32479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (mNextSelectedPosition >= 0) {
32579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            setSelectedPositionInt(mNextSelectedPosition);
32679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
32779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
32879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        recycleAllViews();
32979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
33079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Clear out old views
33179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        removeAllViewsInLayout();
33279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
33379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Make selected view and position it
33479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        mFirstPosition = mSelectedPosition;
33579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        View sel = makeAndAddView(mSelectedPosition);
33679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int width = sel.getMeasuredWidth();
33779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int selectedOffset = childrenLeft;
33879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        switch (mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
33979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            case Gravity.CENTER_HORIZONTAL:
34079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                selectedOffset = childrenLeft + (childrenWidth / 2) - (width / 2);
34179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                break;
34279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            case Gravity.RIGHT:
34379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                selectedOffset = childrenLeft + childrenWidth - width;
34479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                break;
34579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
34679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        sel.offsetLeftAndRight(selectedOffset);
34779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
34879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Flush any cached views that did not get reused above
34979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        mRecycler.clear();
35079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
35179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        invalidate();
35279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
35379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        checkSelectionChanged();
35479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
35579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        mDataChanged = false;
35679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        mNeedSync = false;
35779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        setNextSelectedPositionInt(mSelectedPosition);
35879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
35979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
36079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
36179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Obtain a view, either by pulling an existing view from the recycler or
36279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * by getting a new one from the adapter. If we are animating, make sure
36379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * there is enough information in the view's layout parameters to animate
36479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * from the old to new positions.
36579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
36679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param position Position in the spinner for the view to obtain
36779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @return A view that has been added to the spinner
36879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
36979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    private View makeAndAddView(int position) {
37079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
37179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        View child;
37279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
37379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (!mDataChanged) {
37479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            child = mRecycler.get(position);
37579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if (child != null) {
37679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                // Position the view
37779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                setUpChild(child);
37879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
37979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                return child;
38079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
38179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
38279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
38379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Nothing found in the recycler -- ask the adapter for a view
38479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        child = mAdapter.getView(position, null, this);
38579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
38679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Position the view
38779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        setUpChild(child);
38879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
38979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        return child;
39079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
39179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
39279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
39379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Helper for makeAndAddView to set the position of a view
39479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * and fill out its layout paramters.
39579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     *
39679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param child The view to position
39779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
39879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    private void setUpChild(View child) {
39979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
40079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Respect layout params that are already in the view. Otherwise
40179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // make some up...
40279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        ViewGroup.LayoutParams lp = child.getLayoutParams();
40379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (lp == null) {
40479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            lp = generateDefaultLayoutParams();
40579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
40679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
40779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        addViewInLayout(child, 0, lp);
40879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
40979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        child.setSelected(hasFocus());
41079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
41179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Get measure specs
41279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec,
41379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                mSpinnerPadding.top + mSpinnerPadding.bottom, lp.height);
41479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
41579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                mSpinnerPadding.left + mSpinnerPadding.right, lp.width);
41679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
41779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Measure child
41879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        child.measure(childWidthSpec, childHeightSpec);
41979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
42079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int childLeft;
42179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int childRight;
42279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
42379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Position vertically based on gravity setting
42479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int childTop = mSpinnerPadding.top
42579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                + ((getMeasuredHeight() - mSpinnerPadding.bottom -
42679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                mSpinnerPadding.top - child.getMeasuredHeight()) / 2);
42779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int childBottom = childTop + child.getMeasuredHeight();
42879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
42979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int width = child.getMeasuredWidth();
43079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        childLeft = 0;
43179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        childRight = childLeft + width;
43279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
43379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        child.layout(childLeft, childTop, childRight, childBottom);
43479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
43579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
43679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    @Override
43779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    public boolean performClick() {
43879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        boolean handled = super.performClick();
43979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
44079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (!handled) {
44179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            handled = true;
44279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
44379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if (!mPopup.isShowing()) {
44479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                mPopup.show();
44579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
44679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
44779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
44879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        return handled;
44979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
45079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
45179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    public void onClick(DialogInterface dialog, int which) {
45279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        setSelection(which);
45379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        dialog.dismiss();
45479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
45579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
45679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
45779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Sets the prompt to display when the dialog is shown.
45879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param prompt the prompt to set
45979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
46079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    public void setPrompt(CharSequence prompt) {
46179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        mPopup.setPromptText(prompt);
46279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
46379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
46479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
46579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Sets the prompt to display when the dialog is shown.
46679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @param promptId the resource ID of the prompt to display when the dialog is shown
46779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
46879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    public void setPromptId(int promptId) {
46979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        setPrompt(getContext().getText(promptId));
47079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
47179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
47279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
47379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * @return The prompt to display when the dialog is shown
47479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
47579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    public CharSequence getPrompt() {
47679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        return mPopup.getHintText();
47779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
47879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
47979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    int measureContentWidth(SpinnerAdapter adapter, Drawable background) {
48079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (adapter == null) {
48179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return 0;
48279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
48379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
48479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int width = 0;
48579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        View itemView = null;
48679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int itemType = 0;
48779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        final int widthMeasureSpec =
48879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
48979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        final int heightMeasureSpec =
49079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
49179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
49279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Make sure the number of items we'll measure is capped. If it's a huge data set
49379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // with wildly varying sizes, oh well.
49479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        int start = Math.max(0, getSelectedItemPosition());
49579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        final int end = Math.min(adapter.getCount(), start + MAX_ITEMS_MEASURED);
49679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        final int count = end - start;
49779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        start = Math.max(0, start - (MAX_ITEMS_MEASURED - count));
49879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        for (int i = start; i < end; i++) {
49979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            final int positionType = adapter.getItemViewType(i);
50079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if (positionType != itemType) {
50179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                itemType = positionType;
50279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                itemView = null;
50379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
50479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            itemView = adapter.getView(i, itemView, this);
50579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if (itemView.getLayoutParams() == null) {
50679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                itemView.setLayoutParams(new ViewGroup.LayoutParams(
50779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                        ViewGroup.LayoutParams.WRAP_CONTENT,
50879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                        ViewGroup.LayoutParams.WRAP_CONTENT));
50979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
51079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            itemView.measure(widthMeasureSpec, heightMeasureSpec);
51179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            width = Math.max(width, itemView.getMeasuredWidth());
51279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
51379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
51479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        // Add background padding to measured width
51579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        if (background != null) {
51679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            background.getPadding(mTempRect);
51779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            width += mTempRect.left + mTempRect.right;
51879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
51979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
52079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        return width;
52179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
52279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
52379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
52479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * <p>Wrapper class for an Adapter. Transforms the embedded Adapter instance
52579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * into a ListAdapter.</p>
52679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
52779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    private static class DropDownAdapter implements ListAdapter, SpinnerAdapter {
52879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        private SpinnerAdapter mAdapter;
52979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        private ListAdapter mListAdapter;
53079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
53179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        /**
53279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         * <p>Creates a new ListAdapter wrapper for the specified adapter.</p>
53379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         *
53479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         * @param adapter the Adapter to transform into a ListAdapter
53579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         */
53679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public DropDownAdapter(SpinnerAdapter adapter) {
53779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            this.mAdapter = adapter;
53879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if (adapter instanceof ListAdapter) {
53979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                this.mListAdapter = (ListAdapter) adapter;
54079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
54179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
54279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
54379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public int getCount() {
54479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return mAdapter == null ? 0 : mAdapter.getCount();
54579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
54679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
54779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public Object getItem(int position) {
54879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return mAdapter == null ? null : mAdapter.getItem(position);
54979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
55079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
55179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public long getItemId(int position) {
55279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return mAdapter == null ? -1 : mAdapter.getItemId(position);
55379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
55479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
55579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public View getView(int position, View convertView, ViewGroup parent) {
55679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return getDropDownView(position, convertView, parent);
55779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
55879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
55979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public View getDropDownView(int position, View convertView, ViewGroup parent) {
56079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return mAdapter == null ? null :
56179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                    mAdapter.getDropDownView(position, convertView, parent);
56279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
56379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
56479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public boolean hasStableIds() {
56579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return mAdapter != null && mAdapter.hasStableIds();
56679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
56779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
56879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void registerDataSetObserver(DataSetObserver observer) {
56979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if (mAdapter != null) {
57079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                mAdapter.registerDataSetObserver(observer);
57179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
57279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
57379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
57479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void unregisterDataSetObserver(DataSetObserver observer) {
57579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if (mAdapter != null) {
57679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                mAdapter.unregisterDataSetObserver(observer);
57779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
57879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
57979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
58079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        /**
58179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         * If the wrapped SpinnerAdapter is also a ListAdapter, delegate this call.
58279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         * Otherwise, return true.
58379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         */
58479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public boolean areAllItemsEnabled() {
58579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            final ListAdapter adapter = mListAdapter;
58679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if (adapter != null) {
58779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                return adapter.areAllItemsEnabled();
58879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            } else {
58979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                return true;
59079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
59179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
59279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
59379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        /**
59479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         * If the wrapped SpinnerAdapter is also a ListAdapter, delegate this call.
59579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         * Otherwise, return true.
59679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         */
59779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public boolean isEnabled(int position) {
59879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            final ListAdapter adapter = mListAdapter;
59979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if (adapter != null) {
60079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                return adapter.isEnabled(position);
60179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            } else {
60279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                return true;
60379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
60479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
60579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
60679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public int getItemViewType(int position) {
60779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return 0;
60879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
60979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
61079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public int getViewTypeCount() {
61179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return 1;
61279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
61379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
61479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public boolean isEmpty() {
61579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return getCount() == 0;
61679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
61779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
61879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
61979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    /**
62079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Implements some sort of popup selection interface for selecting a spinner option.
62179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     * Allows for different spinner modes.
62279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes     */
62379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    private interface SpinnerPopup {
62479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void setAdapter(ListAdapter adapter);
62579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
62679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        /**
62779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         * Show the popup
62879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         */
62979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void show();
63079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
63179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        /**
63279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         * Dismiss the popup
63379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         */
63479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void dismiss();
63579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
63679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        /**
63779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         * @return true if the popup is showing, false otherwise.
63879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         */
63979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public boolean isShowing();
64079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
64179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        /**
64279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         * Set hint text to be displayed to the user. This should provide
64379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         * a description of the choice being made.
64479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         * @param hintText Hint text to set.
64579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes         */
64679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void setPromptText(CharSequence hintText);
64779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public CharSequence getHintText();
64879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
64979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
65079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    private class DialogPopup implements SpinnerPopup, DialogInterface.OnClickListener {
65179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        private AlertDialog mPopup;
65279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        private ListAdapter mListAdapter;
65379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        private CharSequence mPrompt;
65479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
65579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void dismiss() {
65679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mPopup.dismiss();
65779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mPopup = null;
65879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
65979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
66079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public boolean isShowing() {
66179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return mPopup != null ? mPopup.isShowing() : false;
66279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
66379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
66479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void setAdapter(ListAdapter adapter) {
66579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mListAdapter = adapter;
66679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
66779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
66879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void setPromptText(CharSequence hintText) {
66979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mPrompt = hintText;
67079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
67179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
67279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public CharSequence getHintText() {
67379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return mPrompt;
67479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
67579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
67679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void show() {
67779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
67879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if (mPrompt != null) {
67979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                builder.setTitle(mPrompt);
68079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
68179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mPopup = builder.setSingleChoiceItems(mListAdapter,
68279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                    getSelectedItemPosition(), this).show();
68379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
68479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
68579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void onClick(DialogInterface dialog, int which) {
68679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            setSelection(which);
687449ba8fe7056873134b0ee02ad5acb615bc7d249Chris Banes            if (mOnItemClickListener != null) {
688449ba8fe7056873134b0ee02ad5acb615bc7d249Chris Banes                performItemClick(null, which, mListAdapter.getItemId(which));
689449ba8fe7056873134b0ee02ad5acb615bc7d249Chris Banes            }
69079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            dismiss();
69179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
69279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
69379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
694da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brown    private class DropdownPopup extends android.support.v7.internal.widget.ListPopupWindow
69579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            implements SpinnerPopup {
69679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        private CharSequence mHintText;
69779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        private ListAdapter mAdapter;
69879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
69979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public DropdownPopup(Context context, AttributeSet attrs, int defStyleRes) {
70079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            super(context, attrs, defStyleRes);
70179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
70279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            setAnchorView(SpinnerICS.this);
70379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            setModal(true);
70479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            setPromptPosition(POSITION_PROMPT_ABOVE);
70579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
70679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            AdapterView.OnItemClickListener listener = new OnItemClickListenerWrapper(
70779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                    new OnItemClickListener() {
70879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                public void onItemClick(AdapterViewICS parent, View v, int position, long id) {
70979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                    SpinnerICS.this.setSelection(position);
710449ba8fe7056873134b0ee02ad5acb615bc7d249Chris Banes                    if (mOnItemClickListener != null) {
711449ba8fe7056873134b0ee02ad5acb615bc7d249Chris Banes                        SpinnerICS.this.performItemClick(v, position, mAdapter.getItemId(position));
712449ba8fe7056873134b0ee02ad5acb615bc7d249Chris Banes                    }
71379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                    dismiss();
71479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                }
71579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            });
71679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
71779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            setOnItemClickListener(listener);
71879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
71979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
72079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        @Override
72179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void setAdapter(ListAdapter adapter) {
72279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            super.setAdapter(adapter);
72379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mAdapter = adapter;
72479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
72579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
72679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public CharSequence getHintText() {
72779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            return mHintText;
72879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
72979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
73079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void setPromptText(CharSequence hintText) {
73179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            // Hint text is ignored for dropdowns, but maintain it here.
73279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            mHintText = hintText;
73379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
73479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes
73579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        @Override
73679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        public void show() {
73779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            final int spinnerPaddingLeft = SpinnerICS.this.getPaddingLeft();
73879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if (mDropDownWidth == WRAP_CONTENT) {
73979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                final int spinnerWidth = SpinnerICS.this.getWidth();
74079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                final int spinnerPaddingRight = SpinnerICS.this.getPaddingRight();
74179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                setContentWidth(Math.max(
74279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                        measureContentWidth((SpinnerAdapter) mAdapter, getBackground()),
74379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                        spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight));
74479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            } else if (mDropDownWidth == FILL_PARENT) {
74579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                final int spinnerWidth = SpinnerICS.this.getWidth();
74679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                final int spinnerPaddingRight = SpinnerICS.this.getPaddingRight();
74779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                setContentWidth(spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight);
74879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            } else {
74979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                setContentWidth(mDropDownWidth);
75079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
75179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            final Drawable background = getBackground();
75279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            int bgOffset = 0;
75379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            if (background != null) {
75479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                background.getPadding(mTempRect);
75579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes                bgOffset = -mTempRect.left;
75679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            }
75779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            setHorizontalOffset(bgOffset + spinnerPaddingLeft);
75879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
75979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            super.show();
76079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
76179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes            setSelection(SpinnerICS.this.getSelectedItemPosition());
76279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes        }
76379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    }
76479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes}
765