From 2add9bcf8c33c59f300551bdb0671bbff0b55794 Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Tue, 2 Jun 2015 14:54:40 -0700 Subject: [PATCH] API review feedback for ThemedSpinnerAdapter, Spinner Moves themed interface out of Spinner and extends SpinnerAdapter, updates Spinner constructor to take a Theme rather than a Context. Does NOT change BaseAdapter to implement ThemedSpinnerAdapter, because the BaseAdapter class does not have any notion of layout inflation and that would break the contract implied by ThemedSpinnerAdapter. Bug: 21571899 Change-Id: Id7e8d630458857ce6c93a6a8b8f920e169ee1152 --- api/current.txt | 18 +++---- api/system-current.txt | 18 +++---- core/java/android/widget/ArrayAdapter.java | 3 +- core/java/android/widget/CursorAdapter.java | 2 +- core/java/android/widget/SimpleAdapter.java | 2 +- core/java/android/widget/Spinner.java | 38 ++++--------- .../android/widget/ThemedSpinnerAdapter.java | 53 +++++++++++++++++++ 7 files changed, 85 insertions(+), 49 deletions(-) create mode 100644 core/java/android/widget/ThemedSpinnerAdapter.java diff --git a/api/current.txt b/api/current.txt index d38e75a642f7b..b909e1ed18575 100644 --- a/api/current.txt +++ b/api/current.txt @@ -39614,7 +39614,7 @@ package android.widget { ctor public AnalogClock(android.content.Context, android.util.AttributeSet, int, int); } - public class ArrayAdapter extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.Spinner.ThemedSpinnerAdapter { + public class ArrayAdapter extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.ThemedSpinnerAdapter { ctor public ArrayAdapter(android.content.Context, int); ctor public ArrayAdapter(android.content.Context, int, int); ctor public ArrayAdapter(android.content.Context, int, T[]); @@ -39855,7 +39855,7 @@ package android.widget { method public abstract void onCheckedChanged(android.widget.CompoundButton, boolean); } - public abstract class CursorAdapter extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.Spinner.ThemedSpinnerAdapter { + public abstract class CursorAdapter extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.ThemedSpinnerAdapter { ctor public deprecated CursorAdapter(android.content.Context, android.database.Cursor); ctor public CursorAdapter(android.content.Context, android.database.Cursor, boolean); ctor public CursorAdapter(android.content.Context, android.database.Cursor, int); @@ -41120,7 +41120,7 @@ package android.widget { method public abstract boolean onShareTargetSelected(android.widget.ShareActionProvider, android.content.Intent); } - public class SimpleAdapter extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.Spinner.ThemedSpinnerAdapter { + public class SimpleAdapter extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.ThemedSpinnerAdapter { ctor public SimpleAdapter(android.content.Context, java.util.List>, int, java.lang.String[], int[]); method public int getCount(); method public android.content.res.Resources.Theme getDropDownViewTheme(); @@ -41249,7 +41249,7 @@ package android.widget { ctor public Spinner(android.content.Context, android.util.AttributeSet, int); ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int); ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int, int); - ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int, int, android.content.Context); + ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int, int, android.content.res.Resources.Theme); method public int getDropDownHorizontalOffset(); method public int getDropDownVerticalOffset(); method public int getDropDownWidth(); @@ -41270,11 +41270,6 @@ package android.widget { field public static final int MODE_DROPDOWN = 1; // 0x1 } - public static abstract interface Spinner.ThemedSpinnerAdapter { - method public abstract android.content.res.Resources.Theme getDropDownViewTheme(); - method public abstract void setDropDownViewTheme(android.content.res.Resources.Theme); - } - public abstract interface SpinnerAdapter implements android.widget.Adapter { method public abstract android.view.View getDropDownView(int, android.view.View, android.view.ViewGroup); } @@ -41676,6 +41671,11 @@ package android.widget { field public static final android.os.Parcelable.Creator CREATOR; } + public abstract interface ThemedSpinnerAdapter implements android.widget.SpinnerAdapter { + method public abstract android.content.res.Resources.Theme getDropDownViewTheme(); + method public abstract void setDropDownViewTheme(android.content.res.Resources.Theme); + } + public class TimePicker extends android.widget.FrameLayout { ctor public TimePicker(android.content.Context); ctor public TimePicker(android.content.Context, android.util.AttributeSet); diff --git a/api/system-current.txt b/api/system-current.txt index 44d8c8ed7f142..a0a9ceac0f83f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -42186,7 +42186,7 @@ package android.widget { ctor public AnalogClock(android.content.Context, android.util.AttributeSet, int, int); } - public class ArrayAdapter extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.Spinner.ThemedSpinnerAdapter { + public class ArrayAdapter extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.ThemedSpinnerAdapter { ctor public ArrayAdapter(android.content.Context, int); ctor public ArrayAdapter(android.content.Context, int, int); ctor public ArrayAdapter(android.content.Context, int, T[]); @@ -42427,7 +42427,7 @@ package android.widget { method public abstract void onCheckedChanged(android.widget.CompoundButton, boolean); } - public abstract class CursorAdapter extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.Spinner.ThemedSpinnerAdapter { + public abstract class CursorAdapter extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.ThemedSpinnerAdapter { ctor public deprecated CursorAdapter(android.content.Context, android.database.Cursor); ctor public CursorAdapter(android.content.Context, android.database.Cursor, boolean); ctor public CursorAdapter(android.content.Context, android.database.Cursor, int); @@ -43692,7 +43692,7 @@ package android.widget { method public abstract boolean onShareTargetSelected(android.widget.ShareActionProvider, android.content.Intent); } - public class SimpleAdapter extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.Spinner.ThemedSpinnerAdapter { + public class SimpleAdapter extends android.widget.BaseAdapter implements android.widget.Filterable android.widget.ThemedSpinnerAdapter { ctor public SimpleAdapter(android.content.Context, java.util.List>, int, java.lang.String[], int[]); method public int getCount(); method public android.content.res.Resources.Theme getDropDownViewTheme(); @@ -43821,7 +43821,7 @@ package android.widget { ctor public Spinner(android.content.Context, android.util.AttributeSet, int); ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int); ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int, int); - ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int, int, android.content.Context); + ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int, int, android.content.res.Resources.Theme); method public int getDropDownHorizontalOffset(); method public int getDropDownVerticalOffset(); method public int getDropDownWidth(); @@ -43842,11 +43842,6 @@ package android.widget { field public static final int MODE_DROPDOWN = 1; // 0x1 } - public static abstract interface Spinner.ThemedSpinnerAdapter { - method public abstract android.content.res.Resources.Theme getDropDownViewTheme(); - method public abstract void setDropDownViewTheme(android.content.res.Resources.Theme); - } - public abstract interface SpinnerAdapter implements android.widget.Adapter { method public abstract android.view.View getDropDownView(int, android.view.View, android.view.ViewGroup); } @@ -44248,6 +44243,11 @@ package android.widget { field public static final android.os.Parcelable.Creator CREATOR; } + public abstract interface ThemedSpinnerAdapter implements android.widget.SpinnerAdapter { + method public abstract android.content.res.Resources.Theme getDropDownViewTheme(); + method public abstract void setDropDownViewTheme(android.content.res.Resources.Theme); + } + public class TimePicker extends android.widget.FrameLayout { ctor public TimePicker(android.content.Context); ctor public TimePicker(android.content.Context, android.util.AttributeSet); diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java index ae94a10ff0360..260854f801532 100644 --- a/core/java/android/widget/ArrayAdapter.java +++ b/core/java/android/widget/ArrayAdapter.java @@ -50,8 +50,7 @@ import java.util.List; * or to have some of data besides toString() results fill the views, * override {@link #getView(int, View, ViewGroup)} to return the type of view you want. */ -public class ArrayAdapter extends BaseAdapter implements Filterable, - Spinner.ThemedSpinnerAdapter { +public class ArrayAdapter extends BaseAdapter implements Filterable, ThemedSpinnerAdapter { /** * Contains the list of objects that represent the data of this ArrayAdapter. * The content of this list is referred to as "the array" in the documentation. diff --git a/core/java/android/widget/CursorAdapter.java b/core/java/android/widget/CursorAdapter.java index d8ce60c9989a5..9fb98db54e725 100644 --- a/core/java/android/widget/CursorAdapter.java +++ b/core/java/android/widget/CursorAdapter.java @@ -38,7 +38,7 @@ import android.view.ViewGroup; * columns. */ public abstract class CursorAdapter extends BaseAdapter implements Filterable, - CursorFilter.CursorFilterClient, Spinner.ThemedSpinnerAdapter { + CursorFilter.CursorFilterClient, ThemedSpinnerAdapter { /** * This field should be made private, so it is hidden from the SDK. * {@hide} diff --git a/core/java/android/widget/SimpleAdapter.java b/core/java/android/widget/SimpleAdapter.java index 2008ba8f0d885..e7760eebb522b 100644 --- a/core/java/android/widget/SimpleAdapter.java +++ b/core/java/android/widget/SimpleAdapter.java @@ -51,7 +51,7 @@ import java.util.Map; * * If no appropriate binding can be found, an {@link IllegalStateException} is thrown. */ -public class SimpleAdapter extends BaseAdapter implements Filterable, Spinner.ThemedSpinnerAdapter { +public class SimpleAdapter extends BaseAdapter implements Filterable, ThemedSpinnerAdapter { private int[] mTo; private String[] mFrom; private ViewBinder mViewBinder; diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index 095cc444c0257..6fe34ddfc0d3b 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.res.Resources; +import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.database.DataSetObserver; import android.graphics.Rect; @@ -217,24 +218,24 @@ public class Spinner extends AbsSpinner implements OnClickListener { * Can be 0 to not look for defaults. * @param mode Constant describing how the user will select choices from * the spinner. - * @param popupContext The context against which the dialog or dropdown - * popup will be inflated. Can be null to use the view - * context. If set, this will override any value - * specified by - * {@link android.R.styleable#Spinner_popupTheme}. + * @param popupTheme The theme against which the dialog or dropdown popup + * should be inflated. May be {@code null} to use the + * view theme. If set, this will override any value + * specified by + * {@link android.R.styleable#Spinner_popupTheme}. * * @see #MODE_DIALOG * @see #MODE_DROPDOWN */ public Spinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes, int mode, - Context popupContext) { + Theme popupTheme) { super(context, attrs, defStyleAttr, defStyleRes); final TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.Spinner, defStyleAttr, defStyleRes); - if (popupContext != null) { - mPopupContext = popupContext; + if (popupTheme != null) { + mPopupContext = new ContextThemeWrapper(context, popupTheme); } else { final int popupThemeResId = a.getResourceId(R.styleable.Spinner_popupTheme, 0); if (popupThemeResId != 0) { @@ -932,9 +933,8 @@ public class Spinner extends AbsSpinner implements OnClickListener { mListAdapter = (ListAdapter) adapter; } - if (dropDownTheme != null && adapter instanceof Spinner.ThemedSpinnerAdapter) { - final Spinner.ThemedSpinnerAdapter themedAdapter = - (Spinner.ThemedSpinnerAdapter) adapter; + if (dropDownTheme != null && adapter instanceof ThemedSpinnerAdapter) { + final ThemedSpinnerAdapter themedAdapter = (ThemedSpinnerAdapter) adapter; if (themedAdapter.getDropDownViewTheme() == null) { themedAdapter.setDropDownViewTheme(dropDownTheme); } @@ -1263,20 +1263,4 @@ 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(); - } } diff --git a/core/java/android/widget/ThemedSpinnerAdapter.java b/core/java/android/widget/ThemedSpinnerAdapter.java new file mode 100644 index 0000000000000..6d92620a0f676 --- /dev/null +++ b/core/java/android/widget/ThemedSpinnerAdapter.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.widget; + +import android.annotation.Nullable; +import android.content.res.Resources; +import android.content.res.Resources.Theme; +import android.view.View; +import android.view.ViewGroup; + +/** + * An extension of SpinnerAdapter that is capable of inflating drop-down views + * against a different theme than normal views. + *

+ * Classes that implement this interface should use the theme provided to + * {@link #setDropDownViewTheme(Theme)} when creating views in + * {@link SpinnerAdapter#getDropDownView(int, View, ViewGroup)}. + */ +public interface ThemedSpinnerAdapter extends SpinnerAdapter { + /** + * Sets the {@link Resources.Theme} against which drop-down views are + * inflated. + * + * @param theme the context against which to inflate drop-down views, or + * {@code null} to use the default theme + * @see SpinnerAdapter#getDropDownView(int, View, ViewGroup) + */ + void setDropDownViewTheme(@Nullable Resources.Theme theme); + + /** + * Returns the value previously set by a call to + * {@link #setDropDownViewTheme(Theme)}. + * + * @return the {@link Resources.Theme} against which drop-down views are + * inflated, or {@code null} if one has not been explicitly set + */ + @Nullable + Resources.Theme getDropDownViewTheme(); +}