diff --git a/api/current.txt b/api/current.txt index 582b7b342a60d..7fe165066146c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -2407,6 +2407,7 @@ package android { field public static final int Widget_Material_Button_Borderless = 16974425; // 0x1030259 field public static final int Widget_Material_Button_Borderless_Colored = 16974426; // 0x103025a field public static final int Widget_Material_Button_Borderless_Small = 16974427; // 0x103025b + field public static final int Widget_Material_Button_Colored = 16974547; // 0x10302d3 field public static final int Widget_Material_Button_Inset = 16974428; // 0x103025c field public static final int Widget_Material_Button_Small = 16974429; // 0x103025d field public static final int Widget_Material_Button_Toggle = 16974430; // 0x103025e @@ -7148,6 +7149,8 @@ package android.content { method public abstract java.io.File getCacheDir(); method public abstract java.lang.ClassLoader getClassLoader(); method public abstract java.io.File getCodeCacheDir(); + method public final int getColor(int); + method public final android.content.res.ColorStateList getColorStateList(int); method public abstract android.content.ContentResolver getContentResolver(); method public abstract java.io.File getDatabasePath(java.lang.String); method public abstract java.io.File getDir(java.lang.String, int); @@ -9076,7 +9079,10 @@ package android.content.res { public class ColorStateList implements android.os.Parcelable { ctor public ColorStateList(int[][], int[]); - method public static android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public void applyTheme(android.content.res.Resources.Theme); + method public boolean canApplyTheme(); + method public static deprecated android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static android.content.res.ColorStateList createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public int describeContents(); method public int getColorForState(int[], int); method public int getDefaultColor(); @@ -9206,8 +9212,10 @@ package android.content.res { method public android.content.res.XmlResourceParser getAnimation(int) throws android.content.res.Resources.NotFoundException; method public final android.content.res.AssetManager getAssets(); method public boolean getBoolean(int) throws android.content.res.Resources.NotFoundException; - method public int getColor(int) throws android.content.res.Resources.NotFoundException; - method public android.content.res.ColorStateList getColorStateList(int) throws android.content.res.Resources.NotFoundException; + method public deprecated int getColor(int) throws android.content.res.Resources.NotFoundException; + method public int getColor(int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException; + method public deprecated android.content.res.ColorStateList getColorStateList(int) throws android.content.res.Resources.NotFoundException; + method public android.content.res.ColorStateList getColorStateList(int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException; method public android.content.res.Configuration getConfiguration(); method public float getDimension(int) throws android.content.res.Resources.NotFoundException; method public int getDimensionPixelOffset(int) throws android.content.res.Resources.NotFoundException; @@ -41764,7 +41772,7 @@ package java.lang { method public static double nextUp(double); method public static float nextUp(float); method public static double pow(double, double); - method public static synchronized double random(); + method public static double random(); method public static double rint(double); method public static long round(double); method public static int round(float); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 015e1ec9a138b..e48478503f352 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -24,6 +24,7 @@ import android.annotation.SystemApi; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; +import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; @@ -392,18 +393,55 @@ public abstract class Context { } /** - * Return a drawable object associated with a particular resource ID and + * Returns a color associated with a particular resource ID and styled for + * the current theme. + * + * @param id The desired resource identifier, as generated by the aapt + * tool. This integer encodes the package, type, and resource + * entry. The value 0 is an invalid identifier. + * @return A single color value in the form 0xAARRGGBB. + * @throws android.content.res.Resources.NotFoundException if the given ID + * does not exist. + */ + @Nullable + public final int getColor(int id) { + return getResources().getColor(id, getTheme()); + } + + /** + * Returns a drawable object associated with a particular resource ID and * styled for the current theme. * * @param id The desired resource identifier, as generated by the aapt * tool. This integer encodes the package, type, and resource * entry. The value 0 is an invalid identifier. - * @return Drawable An object that can be used to draw this resource. + * @return An object that can be used to draw this resource, or + * {@code null} if the resource could not be resolved. + * @throws android.content.res.Resources.NotFoundException if the given ID + * does not exist. */ + @Nullable public final Drawable getDrawable(int id) { return getResources().getDrawable(id, getTheme()); } + /** + * Returns a color state list associated with a particular resource ID and + * styled for the current theme. + * + * @param id The desired resource identifier, as generated by the aapt + * tool. This integer encodes the package, type, and resource + * entry. The value 0 is an invalid identifier. + * @return A color state list, or {@code null} if the resource could not be + * resolved. + * @throws android.content.res.Resources.NotFoundException if the given ID + * does not exist. + */ + @Nullable + public final ColorStateList getColorStateList(int id) { + return getResources().getColorStateList(id, getTheme()); + } + /** * Set the base theme for this context. Note that this should be called * before any views are instantiated in the Context (for example before diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java index 68a39d37dbdc1..b42d8bcb9c4e1 100644 --- a/core/java/android/content/res/ColorStateList.java +++ b/core/java/android/content/res/ColorStateList.java @@ -16,8 +16,12 @@ package android.content.res; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.res.Resources.Theme; import android.graphics.Color; +import com.android.internal.R; import com.android.internal.util.ArrayUtils; import com.android.internal.util.GrowingArrayUtils; @@ -25,6 +29,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.util.AttributeSet; +import android.util.Log; import android.util.MathUtils; import android.util.SparseArray; import android.util.StateSet; @@ -64,15 +69,23 @@ import java.util.Arrays; * List Resource.
*/ public class ColorStateList implements Parcelable { - private int[][] mStateSpecs; // must be parallel to mColors - private int[] mColors; // must be parallel to mStateSpecs - private int mDefaultColor = 0xffff0000; - + private static final String TAG = "ColorStateList"; + private static final int DEFAULT_COLOR = Color.RED; private static final int[][] EMPTY = new int[][] { new int[0] }; private static final SparseArray
+ * The properties of the new ColorStateList can be modified without
+ * affecting the source ColorStateList.
+ *
+ * @param orig the source color state list
*/
+ private ColorStateList(ColorStateList orig) {
+ if (orig != null) {
+ mStateSpecs = orig.mStateSpecs;
+ mDefaultColor = orig.mDefaultColor;
+ mIsOpaque = orig.mIsOpaque;
+
+ // Deep copy, this may change due to theming.
+ mColors = orig.mColors.clone();
+ }
+ }
+
+ /**
+ * Creates a ColorStateList from an XML document.
+ *
+ * @param r Resources against which the ColorStateList should be inflated.
+ * @param parser Parser for the XML document defining the ColorStateList.
+ * @return A new color state list.
+ *
+ * @deprecated Use #createFromXml(Resources, XmlPullParser parser, Theme)
+ */
+ @NonNull
+ @Deprecated
public static ColorStateList createFromXml(Resources r, XmlPullParser parser)
throws XmlPullParserException, IOException {
+ return createFromXml(r, parser, null);
+ }
+
+ /**
+ * Creates a ColorStateList from an XML document using given a set of
+ * {@link Resources} and a {@link Theme}.
+ *
+ * @param r Resources against which the ColorStateList should be inflated.
+ * @param parser Parser for the XML document defining the ColorStateList.
+ * @param theme Optional theme to apply to the color state list, may be
+ * {@code null}.
+ * @return A new color state list.
+ */
+ @NonNull
+ public static ColorStateList createFromXml(@NonNull Resources r, @NonNull XmlPullParser parser,
+ @Nullable Theme theme) throws XmlPullParserException, IOException {
final AttributeSet attrs = Xml.asAttributeSet(parser);
int type;
- while ((type=parser.next()) != XmlPullParser.START_TAG
+ while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
+ // Seek parser to start tag.
}
if (type != XmlPullParser.START_TAG) {
throw new XmlPullParserException("No start tag found");
}
- return createFromXmlInner(r, parser, attrs);
+ return createFromXmlInner(r, parser, attrs, theme);
}
/**
@@ -136,28 +198,31 @@ public class ColorStateList implements Parcelable {
* tag in an XML document, tries to create a ColorStateList from that tag.
*
* @throws XmlPullParserException if the current tag is not <selector>
- * @return A color state list for the current tag.
+ * @return A new color state list for the current tag.
*/
- private static ColorStateList createFromXmlInner(Resources r, XmlPullParser parser,
- AttributeSet attrs) throws XmlPullParserException, IOException {
- final ColorStateList colorStateList;
+ @NonNull
+ private static ColorStateList createFromXmlInner(@NonNull Resources r,
+ @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme)
+ throws XmlPullParserException, IOException {
final String name = parser.getName();
- if (name.equals("selector")) {
- colorStateList = new ColorStateList();
- } else {
+ if (!name.equals("selector")) {
throw new XmlPullParserException(
- parser.getPositionDescription() + ": invalid drawable tag " + name);
+ parser.getPositionDescription() + ": invalid color state list tag " + name);
}
- colorStateList.inflate(r, parser, attrs);
+ final ColorStateList colorStateList = new ColorStateList();
+ colorStateList.inflate(r, parser, attrs, theme);
return colorStateList;
}
/**
- * Creates a new ColorStateList that has the same states and
- * colors as this one but where each color has the specified alpha value
- * (0-255).
+ * Creates a new ColorStateList that has the same states and colors as this
+ * one but where each color has the specified alpha value (0-255).
+ *
+ * @param alpha The new alpha channel value (0-255).
+ * @return A new color state list.
*/
+ @NonNull
public ColorStateList withAlpha(int alpha) {
final int[] colors = new int[mColors.length];
final int len = colors.length;
@@ -171,88 +236,154 @@ public class ColorStateList implements Parcelable {
/**
* Fill in this object based on the contents of an XML "selector" element.
*/
- private void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
+ private void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
+ @NonNull AttributeSet attrs, @Nullable Theme theme)
throws XmlPullParserException, IOException {
- int type;
-
final int innerDepth = parser.getDepth()+1;
int depth;
+ int type;
+
+ int changingConfigurations = 0;
+ int defaultColor = DEFAULT_COLOR;
+
+ boolean hasUnresolvedAttrs = false;
int[][] stateSpecList = ArrayUtils.newUnpaddedArray(int[].class, 20);
+ int[][] themeAttrsList = new int[stateSpecList.length][];
int[] colorList = new int[stateSpecList.length];
int listSize = 0;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && ((depth=parser.getDepth()) >= innerDepth
- || type != XmlPullParser.END_TAG)) {
- if (type != XmlPullParser.START_TAG) {
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) {
+ if (type != XmlPullParser.START_TAG || depth > innerDepth
+ || !parser.getName().equals("item")) {
continue;
}
- if (depth > innerDepth || !parser.getName().equals("item")) {
- continue;
- }
+ final TypedArray a = Resources.obtainAttributes(r, theme, attrs,
+ R.styleable.ColorStateListItem);
+ final int[] themeAttrs = a.extractThemeAttrs();
+ final int baseColor = a.getColor(R.styleable.ColorStateListItem_color, 0);
+ final float alphaMod = a.getFloat(R.styleable.ColorStateListItem_alpha, 1.0f);
- int alphaRes = 0;
- float alpha = 1.0f;
- int colorRes = 0;
- int color = 0xffff0000;
- boolean haveColor = false;
+ changingConfigurations |= a.getChangingConfigurations();
- int i;
+ a.recycle();
+
+ // Parse all unrecognized attributes as state specifiers.
int j = 0;
final int numAttrs = attrs.getAttributeCount();
int[] stateSpec = new int[numAttrs];
- for (i = 0; i < numAttrs; i++) {
+ for (int i = 0; i < numAttrs; i++) {
final int stateResId = attrs.getAttributeNameResource(i);
- if (stateResId == 0) break;
- if (stateResId == com.android.internal.R.attr.alpha) {
- alphaRes = attrs.getAttributeResourceValue(i, 0);
- if (alphaRes == 0) {
- alpha = attrs.getAttributeFloatValue(i, 1.0f);
- }
- } else if (stateResId == com.android.internal.R.attr.color) {
- colorRes = attrs.getAttributeResourceValue(i, 0);
- if (colorRes == 0) {
- color = attrs.getAttributeIntValue(i, color);
- haveColor = true;
- }
- } else {
- stateSpec[j++] = attrs.getAttributeBooleanValue(i, false)
- ? stateResId : -stateResId;
+ switch (stateResId) {
+ case R.attr.color:
+ case R.attr.alpha:
+ // Recognized attribute, ignore.
+ break;
+ default:
+ stateSpec[j++] = attrs.getAttributeBooleanValue(i, false)
+ ? stateResId : -stateResId;
}
}
stateSpec = StateSet.trimStateSet(stateSpec, j);
- if (colorRes != 0) {
- color = r.getColor(colorRes);
- } else if (!haveColor) {
- throw new XmlPullParserException(
- parser.getPositionDescription()
- + ":