diff options
author | Alan Viverette <alanv@google.com> | 2015-01-14 10:43:31 -0800 |
---|---|---|
committer | Alan Viverette <alanv@google.com> | 2015-01-14 10:43:31 -0800 |
commit | b9ead4a91599ca63e947f74f83b67a58bda64a82 (patch) | |
tree | e402c3db4afcf539fce6c379782732aeed19069f /core/java/android/widget/Spinner.java | |
parent | dbf22ccd92dc95e7c93c0485be4bcfb5c966578a (diff) | |
download | frameworks_base-b9ead4a91599ca63e947f74f83b67a58bda64a82.zip frameworks_base-b9ead4a91599ca63e947f74f83b67a58bda64a82.tar.gz frameworks_base-b9ead4a91599ca63e947f74f83b67a58bda64a82.tar.bz2 |
Add popup theme for Spinner, use for actionBarPopupTheme default
Also adds methods for setting the context used to inflate drop-down
views in several adapters.
Bug: 17625714
Change-Id: Id267afa4901c1d46ceb3bc3b10fc642cea1799fe
Diffstat (limited to 'core/java/android/widget/Spinner.java')
-rw-r--r-- | core/java/android/widget/Spinner.java | 116 |
1 files changed, 96 insertions, 20 deletions
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index 5c93b60..192b057 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -16,11 +16,15 @@ package android.widget; +import com.android.internal.R; + +import android.annotation.Nullable; import android.annotation.Widget; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; +import android.content.res.Resources; import android.content.res.TypedArray; import android.database.DataSetObserver; import android.graphics.Rect; @@ -30,6 +34,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; +import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; @@ -74,12 +79,15 @@ public class Spinner extends AbsSpinner implements OnClickListener { * Use a dropdown anchored to the Spinner for selecting spinner options. */ public static final int MODE_DROPDOWN = 1; - + /** * Use the theme-supplied value to select the dropdown mode. */ private static final int MODE_THEME = -1; + /** Context used to inflate the popup window or dialog. */ + private Context mPopupContext; + /** Forwarding listener used to implement drag-to-open. */ private ForwardingListener mForwardingListener; @@ -191,10 +199,18 @@ public class Spinner extends AbsSpinner implements OnClickListener { final TypedArray a = context.obtainStyledAttributes( attrs, com.android.internal.R.styleable.Spinner, defStyleAttr, defStyleRes); + final int popupThemeResId = a.getResourceId( + com.android.internal.R.styleable.Spinner_popupTheme, 0); + if (popupThemeResId != 0) { + mPopupContext = new ContextThemeWrapper(context, popupThemeResId); + } else { + mPopupContext = context; + } + if (mode == MODE_THEME) { mode = a.getInt(com.android.internal.R.styleable.Spinner_spinnerMode, MODE_DIALOG); } - + switch (mode) { case MODE_DIALOG: { mPopup = new DialogPopup(); @@ -202,13 +218,15 @@ public class Spinner extends AbsSpinner implements OnClickListener { } case MODE_DROPDOWN: { - final DropdownPopup popup = new DropdownPopup(context, attrs, defStyleAttr, defStyleRes); + final DropdownPopup popup = new DropdownPopup( + mPopupContext, attrs, defStyleAttr, defStyleRes); - mDropDownWidth = a.getLayoutDimension( - com.android.internal.R.styleable.Spinner_dropDownWidth, + final TypedArray pa = mPopupContext.obtainStyledAttributes( + attrs, R.styleable.Spinner, defStyleAttr, defStyleRes); + mDropDownWidth = pa.getLayoutDimension(R.styleable.Spinner_dropDownWidth, ViewGroup.LayoutParams.WRAP_CONTENT); - popup.setBackgroundDrawable(a.getDrawable( - com.android.internal.R.styleable.Spinner_popupBackground)); + popup.setBackgroundDrawable(pa.getDrawable(R.styleable.Spinner_popupBackground)); + pa.recycle(); mPopup = popup; mForwardingListener = new ForwardingListener(this) { @@ -247,6 +265,27 @@ public class Spinner extends AbsSpinner implements OnClickListener { } /** + * Sets the context against which the Spinner's popup or dialog window is + * inflated. + * <p> + * This method must be called before the popup or dialog window has been + * displayed. + * + * @param popupContext context used to inflate the Spinner's popup or + * dialog window + */ + public void setPopupContext(Context popupContext) { + mPopupContext = popupContext; + } + + /** + * @return the context used to inflate the Spinner's popup or dialog window + */ + public Context getPopupContext() { + return mPopupContext; + } + + /** * Set the background drawable for the spinner's popup window of choices. * Only valid in {@link #MODE_DROPDOWN}; this method is a no-op in other modes. * @@ -259,7 +298,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { Log.e(TAG, "setPopupBackgroundDrawable: incompatible spinner mode; ignoring..."); return; } - ((DropdownPopup) mPopup).setBackgroundDrawable(background); + mPopup.setBackgroundDrawable(background); } /** @@ -271,7 +310,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { * @attr ref android.R.styleable#Spinner_popupBackground */ public void setPopupBackgroundResource(int resId) { - setPopupBackgroundDrawable(getContext().getDrawable(resId)); + setPopupBackgroundDrawable(getPopupContext().getDrawable(resId)); } /** @@ -410,9 +449,17 @@ public class Spinner extends AbsSpinner implements OnClickListener { } /** - * Sets the Adapter used to provide the data which backs this Spinner. + * Sets the {@link SpinnerAdapter} used to provide the data which backs + * this Spinner. + * <p> + * If this Spinner has a popup theme set in XML via the + * {@link android.R.styleable#Spinner_popupTheme popupTheme} attribute, the + * adapter should inflate drop-down views using the same theme. The easiest + * way to achieve this is by using {@link #getPopupContext()} to obtain a + * layout inflater for use in + * {@link SpinnerAdapter#getDropDownView(int, View, ViewGroup)}. * <p> - * Note that Spinner overrides {@link Adapter#getViewTypeCount()} on the + * Spinner overrides {@link Adapter#getViewTypeCount()} on the * Adapter associated with this view. Calling * {@link Adapter#getItemViewType(int) getItemViewType(int)} on the object * returned from {@link #getAdapter()} will always return 0. Calling @@ -440,9 +487,9 @@ public class Spinner extends AbsSpinner implements OnClickListener { } if (mPopup != null) { - mPopup.setAdapter(new DropDownAdapter(adapter)); + mPopup.setAdapter(new DropDownAdapter(adapter, mPopupContext.getTheme())); } else { - mTempAdapter = new DropDownAdapter(adapter); + mTempAdapter = new DropDownAdapter(adapter, mPopupContext.getTheme()); } } @@ -849,14 +896,26 @@ public class Spinner extends AbsSpinner implements OnClickListener { private ListAdapter mListAdapter; /** - * <p>Creates a new ListAdapter wrapper for the specified adapter.</p> + * Creates a new ListAdapter wrapper for the specified adapter. * - * @param adapter the Adapter to transform into a ListAdapter + * @param adapter the SpinnerAdapter to transform into a ListAdapter + * @param dropDownTheme the theme against which to inflate drop-down + * views, may be {@null} to use default theme */ - public DropDownAdapter(SpinnerAdapter adapter) { - this.mAdapter = adapter; + public DropDownAdapter(@Nullable SpinnerAdapter adapter, + @Nullable Resources.Theme dropDownTheme) { + mAdapter = adapter; + if (adapter instanceof ListAdapter) { - this.mListAdapter = (ListAdapter) adapter; + mListAdapter = (ListAdapter) adapter; + } + + if (dropDownTheme != null && adapter instanceof Spinner.ThemedSpinnerAdapter) { + final Spinner.ThemedSpinnerAdapter themedAdapter = + (Spinner.ThemedSpinnerAdapter) adapter; + if (themedAdapter.getDropDownViewTheme() == null) { + themedAdapter.setDropDownViewTheme(dropDownTheme); + } } } @@ -996,7 +1055,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { public void setPromptText(CharSequence hintText) { mPrompt = hintText; } - + public CharSequence getHintText() { return mPrompt; } @@ -1005,7 +1064,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { if (mListAdapter == null) { return; } - AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); + AlertDialog.Builder builder = new AlertDialog.Builder(getPopupContext()); if (mPrompt != null) { builder.setTitle(mPrompt); } @@ -1181,4 +1240,21 @@ public class Spinner extends AbsSpinner implements OnClickListener { } } } + + public interface ThemedSpinnerAdapter { + /** + * Sets the {@link Resources.Theme} against which drop-down views are + * inflated. + * + * @param theme the context against which to inflate drop-down views + * @see SpinnerAdapter#getDropDownView(int, View, ViewGroup) + */ + public void setDropDownViewTheme(Resources.Theme theme); + + /** + * @return The {@link Resources.Theme} against which drop-down views are + * inflated. + */ + public Resources.Theme getDropDownViewTheme(); + } } |