19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.content.res; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.util.ArrayUtils; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.StateSet; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Xml; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.ref.WeakReference; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Arrays; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Lets you map {@link android.view.View} state sets to colors. 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.content.res.ColorStateList}s are created from XML resource files defined in the 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "color" subdirectory directory of an application's resource directory. The XML file contains 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a single "selector" element with a number of "item" elements inside. For example: 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <selector xmlns:android="http://schemas.android.com/apk/res/android"> 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <item android:state_focused="true" android:color="@color/testcolor1"/> 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <item android:state_pressed="true" android:state_enabled="false" android:color="@color/testcolor2" /> 4779dc8ccddd846816d4e0e55405ad0dbefa5b0ff6Romain Guy * <item android:state_enabled="false" android:color="@color/testcolor3" /> 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <item android:color="@color/testcolor5"/> 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </selector> 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre> 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This defines a set of state spec / color pairs where each state spec specifies a set of 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * states that a view must either be in or not be in and the color specifies the color associated 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with that spec. The list of state specs will be processed in order of the items in the XML file. 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * An item with no state spec is considered to match any set of states and is generally useful as 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a final item to be used as a default. Note that if you have such an item before any other items 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the list then any subsequent items will end up being ignored. 588dd87ad9440bc63bc312b06f292adcd2642b1c41Scott Main * <p>For more information, see the guide to <a 598dd87ad9440bc63bc312b06f292adcd2642b1c41Scott Main * href="{@docRoot}guide/topics/resources/color-list-resource.html">Color State 608dd87ad9440bc63bc312b06f292adcd2642b1c41Scott Main * List Resource</a>.</p> 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ColorStateList implements Parcelable { 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int[][] mStateSpecs; // must be parallel to mColors 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int[] mColors; // must be parallel to mStateSpecs 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDefaultColor = 0xffff0000; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int[][] EMPTY = new int[][] { new int[0] }; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final SparseArray<WeakReference<ColorStateList>> sCache = 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new SparseArray<WeakReference<ColorStateList>>(); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ColorStateList() { } 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a ColorStateList that returns the specified mapping from 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * states to colors. 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ColorStateList(int[][] states, int[] colors) { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStateSpecs = states; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColors = colors; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (states.length > 0) { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultColor = colors[0]; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < states.length; i++) { 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (states[i].length == 0) { 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultColor = colors[i]; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates or retrieves a ColorStateList that always returns a single color. 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static ColorStateList valueOf(int color) { 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: should we collect these eventually? 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sCache) { 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WeakReference<ColorStateList> ref = sCache.get(color); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ColorStateList csl = ref != null ? ref.get() : null; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (csl != null) { 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return csl; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project csl = new ColorStateList(EMPTY, new int[] { color }); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sCache.put(color, new WeakReference<ColorStateList>(csl)); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return csl; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a ColorStateList from an XML document, given a set of {@link Resources}. 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static ColorStateList createFromXml(Resources r, XmlPullParser parser) 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AttributeSet attrs = Xml.asAttributeSet(parser); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int type; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((type=parser.next()) != XmlPullParser.START_TAG 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && type != XmlPullParser.END_DOCUMENT) { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != XmlPullParser.START_TAG) { 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new XmlPullParserException("No start tag found"); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return createFromXmlInner(r, parser, attrs); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Create from inside an XML document. Called on a parser positioned at 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a tag in an XML document, tries to create a ColorStateList from that tag. 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns null if the tag is not a valid ColorStateList. 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static ColorStateList createFromXmlInner(Resources r, XmlPullParser parser, 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AttributeSet attrs) throws XmlPullParserException, IOException { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ColorStateList colorStateList; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String name = parser.getName(); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name.equals("selector")) { 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colorStateList = new ColorStateList(); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new XmlPullParserException( 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parser.getPositionDescription() + ": invalid drawable tag " + name); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colorStateList.inflate(r, parser, attrs); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return colorStateList; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a new ColorStateList that has the same states and 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * colors as this one but where each color has the specified alpha value 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (0-255). 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ColorStateList withAlpha(int alpha) { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] colors = new int[mColors.length]; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = colors.length; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < len; i++) { 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors[i] = (mColors[i] & 0xFFFFFF) | (alpha << 24); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new ColorStateList(mStateSpecs, colors); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fill in this object based on the contents of an XML "selector" element. 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void inflate(Resources r, XmlPullParser parser, AttributeSet attrs) 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int type; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int innerDepth = parser.getDepth()+1; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int depth; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int listAllocated = 20; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int listSize = 0; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] colorList = new int[listAllocated]; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[][] stateSpecList = new int[listAllocated][]; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((depth=parser.getDepth()) >= innerDepth 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || type != XmlPullParser.END_TAG)) { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != XmlPullParser.START_TAG) { 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (depth > innerDepth || !parser.getName().equals("item")) { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int colorRes = 0; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int color = 0xffff0000; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean haveColor = false; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int j = 0; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numAttrs = attrs.getAttributeCount(); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] stateSpec = new int[numAttrs]; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i = 0; i < numAttrs; i++) { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int stateResId = attrs.getAttributeNameResource(i); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stateResId == 0) break; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stateResId == com.android.internal.R.attr.color) { 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colorRes = attrs.getAttributeResourceValue(i, 0); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (colorRes == 0) { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color = attrs.getAttributeIntValue(i, color); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project haveColor = true; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stateSpec[j++] = attrs.getAttributeBooleanValue(i, false) 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? stateResId 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : -stateResId; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stateSpec = StateSet.trimStateSet(stateSpec, j); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (colorRes != 0) { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project color = r.getColor(colorRes); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!haveColor) { 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new XmlPullParserException( 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parser.getPositionDescription() 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ": <item> tag requires a 'android:color' attribute."); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listSize == 0 || stateSpec.length == 0) { 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultColor = color; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listSize + 1 >= listAllocated) { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listAllocated = ArrayUtils.idealIntArraySize(listSize + 1); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] ncolor = new int[listAllocated]; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(colorList, 0, ncolor, 0, listSize); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[][] nstate = new int[listAllocated][]; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(stateSpecList, 0, nstate, 0, listSize); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colorList = ncolor; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stateSpecList = nstate; 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colorList[listSize] = color; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stateSpecList[listSize] = stateSpec; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listSize++; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColors = new int[listSize]; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStateSpecs = new int[listSize][]; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(colorList, 0, mColors, 0, listSize); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(stateSpecList, 0, mStateSpecs, 0, listSize); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isStateful() { 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStateSpecs.length > 1; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the color associated with the given set of {@link android.view.View} states. 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param stateSet an array of {@link android.view.View} states 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param defaultColor the color to return if there's not state spec in this 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ColorStateList} that matches the stateSet. 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the color associated with that set of states in this {@link ColorStateList}. 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getColorForState(int[] stateSet, int defaultColor) { 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int setLength = mStateSpecs.length; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < setLength; i++) { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] stateSpec = mStateSpecs[i]; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (StateSet.stateSetMatches(stateSpec, stateSet)) { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mColors[i]; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return defaultColor; 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the default color in this {@link ColorStateList}. 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the default color in this {@link ColorStateList}. 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getDefaultColor() { 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDefaultColor; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "ColorStateList{" + 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "mStateSpecs=" + Arrays.deepToString(mStateSpecs) + 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "mColors=" + Arrays.toString(mColors) + 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "mDefaultColor=" + mDefaultColor + '}'; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int describeContents() { 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void writeToParcel(Parcel dest, int flags) { 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = mStateSpecs.length; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeInt(N); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeIntArray(mStateSpecs[i]); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeIntArray(mColors); 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Parcelable.Creator<ColorStateList> CREATOR = 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new Parcelable.Creator<ColorStateList>() { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ColorStateList[] newArray(int size) { 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new ColorStateList[size]; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ColorStateList createFromParcel(Parcel source) { 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = source.readInt(); 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[][] stateSpecs = new int[N][]; 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stateSpecs[i] = source.createIntArray(); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] colors = source.createIntArray(); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new ColorStateList(stateSpecs, colors); 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 329