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 1980756e38882720860db52f1fcc21fa1505a02abfTor Norbyeimport android.annotation.ColorInt; 2045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viveretteimport android.annotation.NonNull; 2145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viveretteimport android.annotation.Nullable; 2245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viveretteimport android.content.res.Resources.Theme; 23a211dd28b93473c452d68432c602d5209b01c178Alan Viveretteimport android.graphics.Color; 24cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viverette 2545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viveretteimport com.android.internal.R; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.util.ArrayUtils; 27776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinskiimport com.android.internal.util.GrowingArrayUtils; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 3345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viveretteimport android.util.Log; 34cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viveretteimport android.util.MathUtils; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.StateSet; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Xml; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.ref.WeakReference; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Arrays; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Lets you map {@link android.view.View} state sets to colors. 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.content.res.ColorStateList}s are created from XML resource files defined in the 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "color" subdirectory directory of an application's resource directory. The XML file contains 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a single "selector" element with a number of "item" elements inside. For example: 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <selector xmlns:android="http://schemas.android.com/apk/res/android"> 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <item android:state_focused="true" android:color="@color/testcolor1"/> 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <item android:state_pressed="true" android:state_enabled="false" android:color="@color/testcolor2" /> 5779dc8ccddd846816d4e0e55405ad0dbefa5b0ff6Romain Guy * <item android:state_enabled="false" android:color="@color/testcolor3" /> 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <item android:color="@color/testcolor5"/> 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </selector> 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre> 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This defines a set of state spec / color pairs where each state spec specifies a set of 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * states that a view must either be in or not be in and the color specifies the color associated 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with that spec. The list of state specs will be processed in order of the items in the XML file. 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * An item with no state spec is considered to match any set of states and is generally useful as 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the list then any subsequent items will end up being ignored. 688dd87ad9440bc63bc312b06f292adcd2642b1c41Scott Main * <p>For more information, see the guide to <a 698dd87ad9440bc63bc312b06f292adcd2642b1c41Scott Main * href="{@docRoot}guide/topics/resources/color-list-resource.html">Color State 708dd87ad9440bc63bc312b06f292adcd2642b1c41Scott Main * List Resource</a>.</p> 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ColorStateList implements Parcelable { 7345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private static final String TAG = "ColorStateList"; 74e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette 7545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private static final int DEFAULT_COLOR = Color.RED; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int[][] EMPTY = new int[][] { new int[0] }; 77e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette 78e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette /** Thread-safe cache of single-color ColorStateLists. */ 79e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette private static final SparseArray<WeakReference<ColorStateList>> sCache = new SparseArray<>(); 80e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette 81e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette /** Lazily-created factory for this color state list. */ 82e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette private ColorStateListFactory mFactory; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private int[][] mThemeAttrs; 8545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private int mChangingConfigurations; 8645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 8745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private int[][] mStateSpecs; 8845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private int[] mColors; 8945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private int mDefaultColor; 9045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private boolean mIsOpaque; 9145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 9245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private ColorStateList() { 9345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette // Not publicly instantiable. 9445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a ColorStateList that returns the specified mapping from 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * states to colors. 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10080756e38882720860db52f1fcc21fa1505a02abfTor Norbye public ColorStateList(int[][] states, @ColorInt int[] colors) { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStateSpecs = states; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColors = colors; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette onColorsChanged(); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @return A ColorStateList containing a single color. 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette @NonNull 11180756e38882720860db52f1fcc21fa1505a02abfTor Norbye public static ColorStateList valueOf(@ColorInt int color) { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sCache) { 11345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int index = sCache.indexOfKey(color); 11445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (index >= 0) { 11545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final ColorStateList cached = sCache.valueAt(index).get(); 11645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (cached != null) { 11745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return cached; 11845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette // Prune missing entry. 12145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette sCache.removeAt(index); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette // Prune the cache before adding new items. 12545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int N = sCache.size(); 12645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette for (int i = N - 1; i >= 0; i--) { 12745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (sCache.valueAt(i).get() == null) { 12845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette sCache.removeAt(i); 12945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 13045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 13145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 13245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final ColorStateList csl = new ColorStateList(EMPTY, new int[] { color }); 133e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette sCache.put(color, new WeakReference<>(csl)); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return csl; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * Creates a ColorStateList with the same properties as another 14045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * ColorStateList. 14145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * <p> 14245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * The properties of the new ColorStateList can be modified without 14345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * affecting the source ColorStateList. 14445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * 14545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @param orig the source color state list 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private ColorStateList(ColorStateList orig) { 14845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (orig != null) { 149e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mChangingConfigurations = orig.mChangingConfigurations; 15045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mStateSpecs = orig.mStateSpecs; 15145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mDefaultColor = orig.mDefaultColor; 15245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mIsOpaque = orig.mIsOpaque; 15345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 154e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette // Deep copy, these may change due to applyTheme(). 155e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mThemeAttrs = orig.mThemeAttrs.clone(); 15645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mColors = orig.mColors.clone(); 15745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 15845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 15945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 16045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette /** 16145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * Creates a ColorStateList from an XML document. 16245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * 16345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @param r Resources against which the ColorStateList should be inflated. 16445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @param parser Parser for the XML document defining the ColorStateList. 16545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @return A new color state list. 16645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * 16745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @deprecated Use #createFromXml(Resources, XmlPullParser parser, Theme) 16845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette */ 16945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette @NonNull 17045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette @Deprecated 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static ColorStateList createFromXml(Resources r, XmlPullParser parser) 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 17345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return createFromXml(r, parser, null); 17445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 17545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 17645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette /** 17745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * Creates a ColorStateList from an XML document using given a set of 17845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * {@link Resources} and a {@link Theme}. 17945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * 18045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @param r Resources against which the ColorStateList should be inflated. 18145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @param parser Parser for the XML document defining the ColorStateList. 18245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @param theme Optional theme to apply to the color state list, may be 18345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * {@code null}. 18445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @return A new color state list. 18545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette */ 18645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette @NonNull 18745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette public static ColorStateList createFromXml(@NonNull Resources r, @NonNull XmlPullParser parser, 18845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette @Nullable Theme theme) throws XmlPullParserException, IOException { 1893b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette final AttributeSet attrs = Xml.asAttributeSet(parser); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int type; 19245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette while ((type = parser.next()) != XmlPullParser.START_TAG 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && type != XmlPullParser.END_DOCUMENT) { 19445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette // Seek parser to start tag. 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != XmlPullParser.START_TAG) { 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new XmlPullParserException("No start tag found"); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return createFromXmlInner(r, parser, attrs, theme); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2043b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette /** 2053b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * Create from inside an XML document. Called on a parser positioned at a 2063b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * tag in an XML document, tries to create a ColorStateList from that tag. 2073b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * 2083b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * @throws XmlPullParserException if the current tag is not <selector> 20945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @return A new color state list for the current tag. 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 21145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette @NonNull 21245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private static ColorStateList createFromXmlInner(@NonNull Resources r, 21345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme) 21445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette throws XmlPullParserException, IOException { 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String name = parser.getName(); 21645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (!name.equals("selector")) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new XmlPullParserException( 21845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette parser.getPositionDescription() + ": invalid color state list tag " + name); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final ColorStateList colorStateList = new ColorStateList(); 22245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette colorStateList.inflate(r, parser, attrs, theme); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return colorStateList; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 22745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * Creates a new ColorStateList that has the same states and colors as this 22845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * one but where each color has the specified alpha value (0-255). 22945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * 23045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @param alpha The new alpha channel value (0-255). 23145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @return A new color state list. 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 23345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette @NonNull 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ColorStateList withAlpha(int alpha) { 2353b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette final int[] colors = new int[mColors.length]; 2363b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette final int len = colors.length; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < len; i++) { 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors[i] = (mColors[i] & 0xFFFFFF) | (alpha << 24); 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new ColorStateList(mStateSpecs, colors); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fill in this object based on the contents of an XML "selector" element. 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 24745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private void inflate(@NonNull Resources r, @NonNull XmlPullParser parser, 24845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette @NonNull AttributeSet attrs, @Nullable Theme theme) 249cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viverette throws XmlPullParserException, IOException { 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int innerDepth = parser.getDepth()+1; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int depth; 25245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette int type; 25345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 25445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette int changingConfigurations = 0; 25545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette int defaultColor = DEFAULT_COLOR; 25645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 25745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette boolean hasUnresolvedAttrs = false; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski int[][] stateSpecList = ArrayUtils.newUnpaddedArray(int[].class, 20); 26045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette int[][] themeAttrsList = new int[stateSpecList.length][]; 261776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski int[] colorList = new int[stateSpecList.length]; 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int listSize = 0; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 26545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette && ((depth = parser.getDepth()) >= innerDepth || type != XmlPullParser.END_TAG)) { 26645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (type != XmlPullParser.START_TAG || depth > innerDepth 26745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || !parser.getName().equals("item")) { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final TypedArray a = Resources.obtainAttributes(r, theme, attrs, 27245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette R.styleable.ColorStateListItem); 27345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int[] themeAttrs = a.extractThemeAttrs(); 274f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette final int baseColor = a.getColor(R.styleable.ColorStateListItem_color, Color.MAGENTA); 27545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final float alphaMod = a.getFloat(R.styleable.ColorStateListItem_alpha, 1.0f); 27645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 27745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette changingConfigurations |= a.getChangingConfigurations(); 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette a.recycle(); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette // Parse all unrecognized attributes as state specifiers. 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int j = 0; 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numAttrs = attrs.getAttributeCount(); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] stateSpec = new int[numAttrs]; 28545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette for (int i = 0; i < numAttrs; i++) { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int stateResId = attrs.getAttributeNameResource(i); 28745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette switch (stateResId) { 28845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette case R.attr.color: 28945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette case R.attr.alpha: 29045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette // Recognized attribute, ignore. 29145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette break; 29245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette default: 29345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette stateSpec[j++] = attrs.getAttributeBooleanValue(i, false) 29445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette ? stateResId : -stateResId; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stateSpec = StateSet.trimStateSet(stateSpec, j); 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette // Apply alpha modulation. If we couldn't resolve the color or 300f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette // alpha yet, the default values leave us enough information to 301f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette // modulate again during applyTheme(). 30245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int color = modulateColorAlpha(baseColor, alphaMod); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listSize == 0 || stateSpec.length == 0) { 30445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette defaultColor = color; 30545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 30645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 30745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (themeAttrs != null) { 30845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette hasUnresolvedAttrs = true; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 310cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viverette 311776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski colorList = GrowingArrayUtils.append(colorList, listSize, color); 31245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette themeAttrsList = GrowingArrayUtils.append(themeAttrsList, listSize, themeAttrs); 313776abc24cdd18610232a50b997cce3cffa74609bAdam Lesinski stateSpecList = GrowingArrayUtils.append(stateSpecList, listSize, stateSpec); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listSize++; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mChangingConfigurations = changingConfigurations; 31845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mDefaultColor = defaultColor; 31945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 32045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (hasUnresolvedAttrs) { 32145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mThemeAttrs = new int[listSize][]; 32245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette System.arraycopy(themeAttrsList, 0, mThemeAttrs, 0, listSize); 32345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } else { 32445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mThemeAttrs = null; 32545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 32645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColors = new int[listSize]; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStateSpecs = new int[listSize][]; 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(colorList, 0, mColors, 0, listSize); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(stateSpecList, 0, mStateSpecs, 0, listSize); 33145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 33245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette onColorsChanged(); 33345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 33445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 33545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette /** 33645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * Returns whether a theme can be applied to this color state list, which 33745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * usually indicates that the color state list has unresolved theme 33845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * attributes. 33945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * 34045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @return whether a theme can be applied to this color state list 341e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * @hide only for resource preloading 34245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette */ 34345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette public boolean canApplyTheme() { 34445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return mThemeAttrs != null; 34545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 34645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 34745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette /** 34845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * Applies a theme to this color state list. 349e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * <p> 350e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * <strong>Note:</strong> Applying a theme may affect the changing 351e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * configuration parameters of this color state list. After calling this 352e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * method, any dependent configurations must be updated by obtaining the 353e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * new configuration mask from {@link #getChangingConfigurations()}. 35445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * 35545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @param t the theme to apply 35645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette */ 357e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette private void applyTheme(Theme t) { 35845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (mThemeAttrs == null) { 35945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return; 36045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 36145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 36245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette boolean hasUnresolvedAttrs = false; 36345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 36445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int[][] themeAttrsList = mThemeAttrs; 36545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int N = themeAttrsList.length; 36645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette for (int i = 0; i < N; i++) { 36745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (themeAttrsList[i] != null) { 36845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final TypedArray a = t.resolveAttributes(themeAttrsList[i], 36945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette R.styleable.ColorStateListItem); 370f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette 371f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette final float defaultAlphaMod; 372f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette if (themeAttrsList[i][R.styleable.ColorStateListItem_color] != 0) { 373f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette // If the base color hasn't been resolved yet, the current 374f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette // color's alpha channel is either full-opacity (if we 375f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette // haven't resolved the alpha modulation yet) or 376f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette // pre-modulated. Either is okay as a default value. 377f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette defaultAlphaMod = Color.alpha(mColors[i]) / 255.0f; 378f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette } else { 379f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette // Otherwise, the only correct default value is 1. Even if 380f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette // nothing is resolved during this call, we can apply this 381f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette // multiple times without losing of information. 382f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette defaultAlphaMod = 1.0f; 383f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette } 384f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette 38550ba321fbcecd0b050d755ff5a02eba7ab97bb00Alan Viverette // Extract the theme attributes, if any, before attempting to 38650ba321fbcecd0b050d755ff5a02eba7ab97bb00Alan Viverette // read from the typed array. This prevents a crash if we have 38750ba321fbcecd0b050d755ff5a02eba7ab97bb00Alan Viverette // unresolved attrs. 38850ba321fbcecd0b050d755ff5a02eba7ab97bb00Alan Viverette themeAttrsList[i] = a.extractThemeAttrs(themeAttrsList[i]); 38950ba321fbcecd0b050d755ff5a02eba7ab97bb00Alan Viverette if (themeAttrsList[i] != null) { 39050ba321fbcecd0b050d755ff5a02eba7ab97bb00Alan Viverette hasUnresolvedAttrs = true; 39150ba321fbcecd0b050d755ff5a02eba7ab97bb00Alan Viverette } 39250ba321fbcecd0b050d755ff5a02eba7ab97bb00Alan Viverette 39345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int baseColor = a.getColor( 39445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette R.styleable.ColorStateListItem_color, mColors[i]); 39545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final float alphaMod = a.getFloat( 396f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette R.styleable.ColorStateListItem_alpha, defaultAlphaMod); 39745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mColors[i] = modulateColorAlpha(baseColor, alphaMod); 398f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette 399f601440e21f352f5e59dd27e6709c7137cd90090Alan Viverette // Account for any configuration changes. 40045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mChangingConfigurations |= a.getChangingConfigurations(); 40145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 40245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette a.recycle(); 40345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 40445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 40545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 40645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (!hasUnresolvedAttrs) { 40745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mThemeAttrs = null; 40845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 40945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 41045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette onColorsChanged(); 41145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 41245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 413e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette /** 414e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * Returns an appropriately themed color state list. 415e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * 416e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * @param t the theme to apply 417e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * @return a copy of the color state list with the theme applied, or the 418e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * color state list itself if there were no unresolved theme 419e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * attributes 420e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * @hide only for resource preloading 421e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette */ 422e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public ColorStateList obtainForTheme(Theme t) { 423e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (t == null || !canApplyTheme()) { 424e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return this; 425e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette } 426e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette 427e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final ColorStateList clone = new ColorStateList(this); 428e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette clone.applyTheme(t); 429e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return clone; 430e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette } 431e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette 432e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette /** 433e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * Returns a mask of the configuration parameters for which this color 434e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * state list may change, requiring that it be re-created. 435e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * 436e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * @return a mask of the changing configuration parameters, as defined by 437e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * {@link android.content.pm.ActivityInfo} 438e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * 439e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * @see android.content.pm.ActivityInfo 440e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette */ 441e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public int getChangingConfigurations() { 442e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return mChangingConfigurations; 443e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette } 444e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette 44545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private int modulateColorAlpha(int baseColor, float alphaMod) { 44645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (alphaMod == 1.0f) { 44745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return baseColor; 44845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 44945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 45045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int baseAlpha = Color.alpha(baseColor); 45145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int alpha = MathUtils.constrain((int) (baseAlpha * alphaMod + 0.5f), 0, 255); 452e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return (baseColor & 0xFFFFFF) | (alpha << 24); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4553b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette /** 4563b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * Indicates whether this color state list contains more than one state spec 4573b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * and will change color based on state. 4583b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * 4593b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * @return True if this color state list changes color based on state, false 4603b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * otherwise. 4613b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * @see #getColorForState(int[], int) 4623b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette */ 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isStateful() { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStateSpecs.length > 1; 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 466a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 4673b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette /** 4683b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * Indicates whether this color state list is opaque, which means that every 4693b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * color returned from {@link #getColorForState(int[], int)} has an alpha 4703b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * value of 255. 4713b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * 4723b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette * @return True if this color state list is opaque. 4733b5c4272db3e089c4a06d2db2ddf2aee5ebb6281Alan Viverette */ 474a211dd28b93473c452d68432c602d5209b01c178Alan Viverette public boolean isOpaque() { 47545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return mIsOpaque; 476a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 477a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 47945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * Return the color associated with the given set of 48045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * {@link android.view.View} states. 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param stateSet an array of {@link android.view.View} states 48345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * @param defaultColor the color to return if there's no matching state 48445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * spec in this {@link ColorStateList} that matches the 48545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * stateSet. 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the color associated with that set of states in this {@link ColorStateList}. 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 48945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette public int getColorForState(@Nullable int[] stateSet, int defaultColor) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int setLength = mStateSpecs.length; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < setLength; i++) { 49245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int[] stateSpec = mStateSpecs[i]; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (StateSet.stateSetMatches(stateSpec, stateSet)) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mColors[i]; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return defaultColor; 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the default color in this {@link ColorStateList}. 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the default color in this {@link ColorStateList}. 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 50580756e38882720860db52f1fcc21fa1505a02abfTor Norbye @ColorInt 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getDefaultColor() { 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDefaultColor; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 51039fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi /** 51145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * Return the states in this {@link ColorStateList}. The returned array 51245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * should not be modified. 51345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * 51439fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi * @return the states in this {@link ColorStateList} 51539fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi * @hide 51639fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi */ 51739fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi public int[][] getStates() { 51839fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi return mStateSpecs; 51939fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi } 52039fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi 52139fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi /** 52245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * Return the colors in this {@link ColorStateList}. The returned array 52345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * should not be modified. 52445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * 52539fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi * @return the colors in this {@link ColorStateList} 52639fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi * @hide 52739fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi */ 52839fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi public int[] getColors() { 52939fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi return mColors; 53039fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi } 53139fa59fc4907d3c8faad41bf20e1f855dbcda5e6Jorim Jaggi 5320ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette /** 5330ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Returns whether the specified state is referenced in any of the state 5340ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * specs contained within this ColorStateList. 5350ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * <p> 5360ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * Any reference, either positive or negative {ex. ~R.attr.state_enabled}, 5370ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * will cause this method to return {@code true}. Wildcards are not counted 5380ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * as references. 5390ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * 5400ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @param state the state to search for 5410ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @return {@code true} if the state if referenced, {@code false} otherwise 5420ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette * @hide Use only as directed. For internal use only. 5430ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette */ 5440ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette public boolean hasState(int state) { 5450ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int[][] stateSpecs = mStateSpecs; 5460ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int specCount = stateSpecs.length; 5470ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette for (int specIndex = 0; specIndex < specCount; specIndex++) { 5480ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int[] states = stateSpecs[specIndex]; 5490ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette final int stateCount = states.length; 5500ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette for (int stateIndex = 0; stateIndex < stateCount; stateIndex++) { 5510ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette if (states[stateIndex] == state || states[stateIndex] == ~state) { 5520ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return true; 5530ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 5540ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 5550ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 5560ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette return false; 5570ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette } 5580ef59ac0e57e9b99d174d4a53f7d9639357743acAlan Viverette 559cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viverette @Override 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "ColorStateList{" + 56245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette "mThemeAttrs=" + Arrays.deepToString(mThemeAttrs) + 56345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette "mChangingConfigurations=" + mChangingConfigurations + 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "mStateSpecs=" + Arrays.deepToString(mStateSpecs) + 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "mColors=" + Arrays.toString(mColors) + 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "mDefaultColor=" + mDefaultColor + '}'; 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 56945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette /** 57045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette * Updates the default color and opacity. 57145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette */ 57245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private void onColorsChanged() { 57345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette int defaultColor = DEFAULT_COLOR; 57445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette boolean isOpaque = true; 57545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 57645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int[][] states = mStateSpecs; 57745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int[] colors = mColors; 57845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final int N = states.length; 57945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (N > 0) { 58045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette defaultColor = colors[0]; 58145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 58245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette for (int i = N - 1; i > 0; i--) { 58345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (states[i].length == 0) { 58445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette defaultColor = colors[i]; 58545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette break; 58645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 58745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 58845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 58945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette for (int i = 0; i < N; i++) { 59045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (Color.alpha(colors[i]) != 0xFF) { 59145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette isOpaque = false; 59245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette break; 59345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 59445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 59545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 59645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 59745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mDefaultColor = defaultColor; 59845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mIsOpaque = isOpaque; 59945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 60045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 60145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette /** 602e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * @return a factory that can create new instances of this ColorStateList 603e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * @hide only for resource preloading 60445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette */ 605e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public ConstantState<ColorStateList> getConstantState() { 6064feb3260152b2ddbd4a96c43c09cd1ed3cf2d3fbJohn Reck if (mFactory == null) { 607e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mFactory = new ColorStateListFactory(this); 608e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette } 609e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return mFactory; 61045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 61145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 612e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette private static class ColorStateListFactory extends ConstantState<ColorStateList> { 613e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette private final ColorStateList mSrc; 61445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 61545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette public ColorStateListFactory(ColorStateList src) { 61645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mSrc = src; 61745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 61845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 61945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette @Override 62045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette public int getChangingConfigurations() { 62145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return mSrc.mChangingConfigurations; 62245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 62345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 62445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette @Override 62545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette public ColorStateList newInstance() { 62645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return mSrc; 62745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 62845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 62945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette @Override 63045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette public ColorStateList newInstance(Resources res, Theme theme) { 631e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return mSrc.obtainForTheme(theme); 63245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 63345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 63445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 635cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viverette @Override 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int describeContents() { 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 640cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viverette @Override 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void writeToParcel(Parcel dest, int flags) { 64245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (canApplyTheme()) { 64345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette Log.w(TAG, "Wrote partially-resolved ColorStateList to parcel!"); 64445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = mStateSpecs.length; 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeInt(N); 647cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viverette for (int i = 0; i < N; i++) { 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeIntArray(mStateSpecs[i]); 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dest.writeIntArray(mColors); 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final Parcelable.Creator<ColorStateList> CREATOR = 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new Parcelable.Creator<ColorStateList>() { 655cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viverette @Override 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ColorStateList[] newArray(int size) { 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new ColorStateList[size]; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 660cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viverette @Override 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ColorStateList createFromParcel(Parcel source) { 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = source.readInt(); 663cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viverette final int[][] stateSpecs = new int[N][]; 664cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viverette for (int i = 0; i < N; i++) { 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stateSpecs[i] = source.createIntArray(); 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 667cc3f33853b8ea5ce56ebfb14fdc3c000a45e0d78Alan Viverette final int[] colors = source.createIntArray(); 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new ColorStateList(stateSpecs, colors); 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 672