GradientColor.java revision 0b9295d06750dc6da032a2b2092e2c500c65393f
1dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu/*
2dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Copyright (C) 2016 The Android Open Source Project
3dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu *
4dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Licensed under the Apache License, Version 2.0 (the "License");
5dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * you may not use this file except in compliance with the License.
6dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * You may obtain a copy of the License at
7dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu *
8dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu *      http://www.apache.org/licenses/LICENSE-2.0
9dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu *
10dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Unless required by applicable law or agreed to in writing, software
11dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * distributed under the License is distributed on an "AS IS" BASIS,
12dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * See the License for the specific language governing permissions and
14dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * limitations under the License.
15dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */
16dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
17dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhupackage android.content.res;
18dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
19dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.annotation.ColorInt;
201664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhuimport android.annotation.IntDef;
21dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.annotation.NonNull;
22dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.annotation.Nullable;
23ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viveretteimport android.content.pm.ActivityInfo.Config;
24dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.content.res.Resources.Theme;
25dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
26dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport com.android.internal.R;
27dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport com.android.internal.util.GrowingArrayUtils;
28dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
29dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport org.xmlpull.v1.XmlPullParser;
30dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport org.xmlpull.v1.XmlPullParserException;
31dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
32dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.graphics.LinearGradient;
33dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.graphics.RadialGradient;
34dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.graphics.Shader;
35dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.graphics.SweepGradient;
36dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.graphics.drawable.GradientDrawable;
37dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.util.AttributeSet;
38dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.util.Log;
39dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.util.Xml;
40dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
41dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport java.io.IOException;
421664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhuimport java.lang.annotation.Retention;
431664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhuimport java.lang.annotation.RetentionPolicy;
44dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
451664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu/**
461664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * Lets you define a gradient color, which is used inside
471664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * {@link android.graphics.drawable.VectorDrawable}.
481664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu *
491664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * {@link android.content.res.GradientColor}s are created from XML resource files defined in the
501664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * "color" subdirectory directory of an application's resource directory.  The XML file contains
511664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * a single "gradient" element with a number of attributes and elements inside.  For example:
521664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * <pre>
531664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * &lt;gradient xmlns:android="http://schemas.android.com/apk/res/android"&gt;
541664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu *   &lt;android:startColor="?android:attr/colorPrimary"/&gt;
551664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu *   &lt;android:endColor="?android:attr/colorControlActivated"/&gt;
561664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu *   &lt;.../&gt;
571664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu *   &lt;android:type="linear"/&gt;
581664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * &lt;/gradient&gt;
591664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * </pre>
601664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu *
611664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * This can describe either a {@link android.graphics.LinearGradient},
621664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * {@link android.graphics.RadialGradient}, or {@link android.graphics.SweepGradient}.
631664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu *
641664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * Note that different attributes are relevant for different types of gradient.
651664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * For example, android:gradientRadius is only applied to RadialGradient.
661664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * androd:centerX and android:centerY are only applied to SweepGradient or RadialGradient.
671664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * android:startX, android:startY, android:endX and android:endY are only applied to LinearGradient.
681664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu *
691664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * Also note if any color "item" element is defined, then startColor, centerColor and endColor will
701664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu * be ignored.
711664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu */
72dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhupublic class GradientColor extends ComplexColor {
73dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private static final String TAG = "GradientColor";
74dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
75dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private static final boolean DBG_GRADIENT = false;
76dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
771664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu    @IntDef({TILE_MODE_CLAMP, TILE_MODE_REPEAT, TILE_MODE_MIRROR})
781664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu    @Retention(RetentionPolicy.SOURCE)
791664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu    private @interface GradientTileMode {}
801664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu    private static final int TILE_MODE_CLAMP = 0;
811664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu    private static final int TILE_MODE_REPEAT = 1;
821664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu    private static final int TILE_MODE_MIRROR = 2;
831664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu
84dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /** Lazily-created factory for this GradientColor. */
85dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private GradientColorFactory mFactory;
86dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
87ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette    private @Config int mChangingConfigurations;
88dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private int mDefaultColor;
89dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
90dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    // After parsing all the attributes from XML, this shader is the ultimate result containing
91dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    // all the XML information.
92dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private Shader mShader = null;
93dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
941664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu    // Below are the attributes at the root element <gradient>.
951664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu    // NOTE: they need to be copied in the copy constructor!
96dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private int mGradientType = GradientDrawable.LINEAR_GRADIENT;
97dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
98dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private float mCenterX = 0f;
99dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private float mCenterY = 0f;
100dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
101dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private float mStartX = 0f;
102dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private float mStartY = 0f;
103dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private float mEndX = 0f;
104dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private float mEndY = 0f;
105dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
106dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private int mStartColor = 0;
107dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private int mCenterColor = 0;
108dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private int mEndColor = 0;
109dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private boolean mHasCenterColor = false;
110dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
1111664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu    private int mTileMode = 0; // Clamp mode.
1121664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu
113dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private float mGradientRadius = 0f;
114dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
115dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    // Below are the attributes for the <item> element.
116dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private int[] mItemColors;
117dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private float[] mItemOffsets;
118dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
119dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    // Theme attributes for the root and item elements.
120dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private int[] mThemeAttrs;
121dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private int[][] mItemsThemeAttrs;
122dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
123dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private GradientColor() {
124dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
125dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
126dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private GradientColor(GradientColor copy) {
127dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (copy != null) {
128dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mChangingConfigurations = copy.mChangingConfigurations;
129dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mDefaultColor = copy.mDefaultColor;
130dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mShader = copy.mShader;
131dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mGradientType = copy.mGradientType;
132dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mCenterX = copy.mCenterX;
133dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mCenterY = copy.mCenterY;
134dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mStartX = copy.mStartX;
135dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mStartY = copy.mStartY;
136dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mEndX = copy.mEndX;
137dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mEndY = copy.mEndY;
138dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mStartColor = copy.mStartColor;
139dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mCenterColor = copy.mCenterColor;
140dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mEndColor = copy.mEndColor;
141dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mHasCenterColor = copy.mHasCenterColor;
142dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mGradientRadius = copy.mGradientRadius;
1431664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu            mTileMode = copy.mTileMode;
144dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
145dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (copy.mItemColors != null) {
146dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                mItemColors = copy.mItemColors.clone();
147dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
148dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (copy.mItemOffsets != null) {
149dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                mItemOffsets = copy.mItemOffsets.clone();
150dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
151dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
152dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (copy.mThemeAttrs != null) {
153dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                mThemeAttrs = copy.mThemeAttrs.clone();
154dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
155dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (copy.mItemsThemeAttrs != null) {
156dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                mItemsThemeAttrs = copy.mItemsThemeAttrs.clone();
157dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
158dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
159dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
160dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
1611664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu    // Set the default to clamp mode.
1621664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu    private static Shader.TileMode parseTileMode(@GradientTileMode int tileMode) {
1631664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu        switch (tileMode) {
1641664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu            case TILE_MODE_CLAMP:
1651664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu                return Shader.TileMode.CLAMP;
1661664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu            case TILE_MODE_REPEAT:
1671664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu                return Shader.TileMode.REPEAT;
1681664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu            case TILE_MODE_MIRROR:
1691664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu                return Shader.TileMode.MIRROR;
1701664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu            default:
1711664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu                return Shader.TileMode.CLAMP;
1721664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu        }
1731664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu    }
1741664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu
175dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
176dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * Update the root level's attributes, either for inflate or applyTheme.
177dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
178dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private void updateRootElementState(TypedArray a) {
179dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        // Extract the theme attributes, if any.
180dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mThemeAttrs = a.extractThemeAttrs();
181dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
182dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mStartX = a.getFloat(
183dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                R.styleable.GradientColor_startX, mStartX);
184dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mStartY = a.getFloat(
185dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                R.styleable.GradientColor_startY, mStartY);
186dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mEndX = a.getFloat(
187dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                R.styleable.GradientColor_endX, mEndX);
188dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mEndY = a.getFloat(
189dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                R.styleable.GradientColor_endY, mEndY);
190dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
191dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mCenterX = a.getFloat(
192dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                R.styleable.GradientColor_centerX, mCenterX);
193dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mCenterY = a.getFloat(
194dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                R.styleable.GradientColor_centerY, mCenterY);
195dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
196dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mGradientType = a.getInt(
197dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                R.styleable.GradientColor_type, mGradientType);
198dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
199dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mStartColor = a.getColor(
200dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                R.styleable.GradientColor_startColor, mStartColor);
201dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mHasCenterColor |= a.hasValue(
202dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                R.styleable.GradientColor_centerColor);
203dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mCenterColor = a.getColor(
204dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                R.styleable.GradientColor_centerColor, mCenterColor);
205dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mEndColor = a.getColor(
206dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                R.styleable.GradientColor_endColor, mEndColor);
207dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
2081664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu        mTileMode = a.getInt(
2091664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu                R.styleable.GradientColor_tileMode, mTileMode);
2101664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu
211dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (DBG_GRADIENT) {
212dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            Log.v(TAG, "hasCenterColor is " + mHasCenterColor);
213dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (mHasCenterColor) {
214dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                Log.v(TAG, "centerColor:" + mCenterColor);
215dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
216dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            Log.v(TAG, "startColor: " + mStartColor);
217dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            Log.v(TAG, "endColor: " + mEndColor);
2181664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu            Log.v(TAG, "tileMode: " + mTileMode);
219dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
220dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
221dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mGradientRadius = a.getFloat(R.styleable.GradientColor_gradientRadius,
222dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                mGradientRadius);
223dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
224dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
225dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
226dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * Check if the XML content is valid.
227dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     *
228dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * @throws XmlPullParserException if errors were found.
229dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
230dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private void validateXmlContent() throws XmlPullParserException {
231dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (mGradientRadius <= 0
232dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                && mGradientType == GradientDrawable.RADIAL_GRADIENT) {
233dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            throw new XmlPullParserException(
234dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                    "<gradient> tag requires 'gradientRadius' "
235dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                            + "attribute with radial type");
236dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
237dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
238dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
239dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
240dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * The shader information will be applied to the native VectorDrawable's path.
241dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * @hide
242dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
243dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    public Shader getShader() {
244dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        return mShader;
245dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
246dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
247dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
248dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * A public method to create GradientColor from a XML resource.
249dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
250dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    public static GradientColor createFromXml(Resources r, XmlResourceParser parser, Theme theme)
251dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            throws XmlPullParserException, IOException {
252dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        final AttributeSet attrs = Xml.asAttributeSet(parser);
253dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
254dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        int type;
255dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        while ((type = parser.next()) != XmlPullParser.START_TAG
256dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                && type != XmlPullParser.END_DOCUMENT) {
257dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            // Seek parser to start tag.
258dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
259dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
260dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (type != XmlPullParser.START_TAG) {
261dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            throw new XmlPullParserException("No start tag found");
262dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
263dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
264dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        return createFromXmlInner(r, parser, attrs, theme);
265dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
266dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
267dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
268dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * Create from inside an XML document. Called on a parser positioned at a
269dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * tag in an XML document, tries to create a GradientColor from that tag.
270dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     *
271dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * @return A new GradientColor for the current tag.
272dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * @throws XmlPullParserException if the current tag is not &lt;gradient>
273dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
274dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    @NonNull
275dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    static GradientColor createFromXmlInner(@NonNull Resources r,
276dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme)
277dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            throws XmlPullParserException, IOException {
278dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        final String name = parser.getName();
279dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (!name.equals("gradient")) {
280dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            throw new XmlPullParserException(
281dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                    parser.getPositionDescription() + ": invalid gradient color tag " + name);
282dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
283dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
284dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        final GradientColor gradientColor = new GradientColor();
285dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        gradientColor.inflate(r, parser, attrs, theme);
286dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        return gradientColor;
287dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
288dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
289dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
290dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * Fill in this object based on the contents of an XML "gradient" element.
291dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
292dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private void inflate(@NonNull Resources r, @NonNull XmlPullParser parser,
293dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            @NonNull AttributeSet attrs, @Nullable Theme theme)
294dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            throws XmlPullParserException, IOException {
295dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        final TypedArray a = Resources.obtainAttributes(r, theme, attrs, R.styleable.GradientColor);
296dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        updateRootElementState(a);
297dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mChangingConfigurations |= a.getChangingConfigurations();
298dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        a.recycle();
299dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
300dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        // Check correctness and throw exception if errors found.
301dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        validateXmlContent();
302dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
303dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        inflateChildElements(r, parser, attrs, theme);
304dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
305dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        onColorsChange();
306dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
307dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
308dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
309dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * Inflates child elements "item"s for each color stop.
310dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     *
311dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * Note that at root level, we need to save ThemeAttrs for theme applied later.
312dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * Here similarly, at each child item, we need to save the theme's attributes, and apply theme
313dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * later as applyItemsAttrsTheme().
314dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
315dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private void inflateChildElements(@NonNull Resources r, @NonNull XmlPullParser parser,
316dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            @NonNull AttributeSet attrs, @NonNull Theme theme)
317dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            throws XmlPullParserException, IOException {
318dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        final int innerDepth = parser.getDepth() + 1;
319dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        int type;
320dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        int depth;
321dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
322dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        // Pre-allocate the array with some size, for better performance.
323dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        float[] offsetList = new float[20];
324dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        int[] colorList = new int[offsetList.length];
325dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        int[][] themeAttrsList = new int[offsetList.length][];
326dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
327dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        int listSize = 0;
328dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        boolean hasUnresolvedAttrs = false;
329dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
330dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                && ((depth = parser.getDepth()) >= innerDepth
331dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                || type != XmlPullParser.END_TAG)) {
332dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (type != XmlPullParser.START_TAG) {
333dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                continue;
334dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
335dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (depth > innerDepth || !parser.getName().equals("item")) {
336dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                continue;
337dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
338dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
339dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            final TypedArray a = Resources.obtainAttributes(r, theme, attrs,
340dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                    R.styleable.GradientColorItem);
341dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            boolean hasColor = a.hasValue(R.styleable.GradientColorItem_color);
342dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            boolean hasOffset = a.hasValue(R.styleable.GradientColorItem_offset);
343dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (!hasColor || !hasOffset) {
344dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                throw new XmlPullParserException(
345dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                        parser.getPositionDescription()
346dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                                + ": <item> tag requires a 'color' attribute and a 'offset' "
347dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                                + "attribute!");
348dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
349dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
350dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            final int[] themeAttrs = a.extractThemeAttrs();
351dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            int color = a.getColor(R.styleable.GradientColorItem_color, 0);
352dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            float offset = a.getFloat(R.styleable.GradientColorItem_offset, 0);
353dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
354dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (DBG_GRADIENT) {
355dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                Log.v(TAG, "new item color " + color + " " + Integer.toHexString(color));
356dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                Log.v(TAG, "offset" + offset);
357dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
358dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mChangingConfigurations |= a.getChangingConfigurations();
359dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            a.recycle();
360dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
361dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (themeAttrs != null) {
362dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                hasUnresolvedAttrs = true;
363dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
364dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
365dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            colorList = GrowingArrayUtils.append(colorList, listSize, color);
366dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            offsetList = GrowingArrayUtils.append(offsetList, listSize, offset);
367dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            themeAttrsList = GrowingArrayUtils.append(themeAttrsList, listSize, themeAttrs);
368dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            listSize++;
369dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
370dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (listSize > 0) {
371dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (hasUnresolvedAttrs) {
372dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                mItemsThemeAttrs = new int[listSize][];
373dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                System.arraycopy(themeAttrsList, 0, mItemsThemeAttrs, 0, listSize);
374dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            } else {
375dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                mItemsThemeAttrs = null;
376dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
377dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
378dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mItemColors = new int[listSize];
379dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mItemOffsets = new float[listSize];
380dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            System.arraycopy(colorList, 0, mItemColors, 0, listSize);
381dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            System.arraycopy(offsetList, 0, mItemOffsets, 0, listSize);
382dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
383dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
384dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
385dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
386dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * Apply theme to all the items.
387dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
388dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private void applyItemsAttrsTheme(Theme t) {
389dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (mItemsThemeAttrs == null) {
390dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            return;
391dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
392dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
393dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        boolean hasUnresolvedAttrs = false;
394dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
395dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        final int[][] themeAttrsList = mItemsThemeAttrs;
396dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        final int N = themeAttrsList.length;
397dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        for (int i = 0; i < N; i++) {
398dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (themeAttrsList[i] != null) {
399dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                final TypedArray a = t.resolveAttributes(themeAttrsList[i],
400dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                        R.styleable.GradientColorItem);
401dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
402dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                // Extract the theme attributes, if any, before attempting to
403dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                // read from the typed array. This prevents a crash if we have
404dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                // unresolved attrs.
405dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                themeAttrsList[i] = a.extractThemeAttrs(themeAttrsList[i]);
406dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                if (themeAttrsList[i] != null) {
407dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                    hasUnresolvedAttrs = true;
408dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                }
409dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
410dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                mItemColors[i] = a.getColor(R.styleable.GradientColorItem_color, mItemColors[i]);
411dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                mItemOffsets[i] = a.getFloat(R.styleable.GradientColorItem_offset, mItemOffsets[i]);
412dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                if (DBG_GRADIENT) {
413dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                    Log.v(TAG, "applyItemsAttrsTheme Colors[i] " + i + " " +
414dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                            Integer.toHexString(mItemColors[i]));
415dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                    Log.v(TAG, "Offsets[i] " + i + " " + mItemOffsets[i]);
416dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                }
417dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
418dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                // Account for any configuration changes.
419dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                mChangingConfigurations |= a.getChangingConfigurations();
420dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
421dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                a.recycle();
422dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
423dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
424dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
425dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (!hasUnresolvedAttrs) {
426dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mItemsThemeAttrs = null;
427dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
428dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
429dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
430dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private void onColorsChange() {
431dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        int[] tempColors = null;
432dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        float[] tempOffsets = null;
433dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
434dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (mItemColors != null) {
435dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            int length = mItemColors.length;
436dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            tempColors = new int[length];
437dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            tempOffsets = new float[length];
438dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
439dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            for (int i = 0; i < length; i++) {
440dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempColors[i] = mItemColors[i];
441dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempOffsets[i] = mItemOffsets[i];
442dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
443dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        } else {
444dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (mHasCenterColor) {
445dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempColors = new int[3];
446dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempColors[0] = mStartColor;
447dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempColors[1] = mCenterColor;
448dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempColors[2] = mEndColor;
449dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
450dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempOffsets = new float[3];
451dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempOffsets[0] = 0.0f;
452dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                // Since 0.5f is default value, try to take the one that isn't 0.5f
453dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempOffsets[1] = 0.5f;
454dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempOffsets[2] = 1f;
455dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            } else {
456dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempColors = new int[2];
457dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempColors[0] = mStartColor;
458dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                tempColors[1] = mEndColor;
459dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
460dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
461dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (tempColors.length < 2) {
462dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            Log.w(TAG, "<gradient> tag requires 2 color values specified!" + tempColors.length
463dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                    + " " + tempColors);
464dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
465dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
466dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (mGradientType == GradientDrawable.LINEAR_GRADIENT) {
467dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mShader = new LinearGradient(mStartX, mStartY, mEndX, mEndY, tempColors, tempOffsets,
4681664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu                    parseTileMode(mTileMode));
469dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        } else {
470dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            if (mGradientType == GradientDrawable.RADIAL_GRADIENT) {
471dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                mShader = new RadialGradient(mCenterX, mCenterY, mGradientRadius, tempColors,
4721664a829eb08dd5c0f567f6466368ef1d1895e36Teng-Hui Zhu                        tempOffsets, parseTileMode(mTileMode));
473dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            } else {
474dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu                mShader = new SweepGradient(mCenterX, mCenterY, tempColors, tempOffsets);
475dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
476dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
477dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mDefaultColor = tempColors[0];
478dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
479dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
480dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
481dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * For Gradient color, the default color is not very useful, since the gradient will override
482dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * the color information anyway.
483dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
484dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    @Override
485dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    @ColorInt
486dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    public int getDefaultColor() {
487dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        return mDefaultColor;
488dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
489dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
490dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
491dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * Similar to ColorStateList, setup constant state and its factory.
492dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * @hide only for resource preloading
493dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
494dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    @Override
495dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    public ConstantState<ComplexColor> getConstantState() {
496dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (mFactory == null) {
497dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mFactory = new GradientColorFactory(this);
498dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
499dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        return mFactory;
500dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
501dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
502dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private static class GradientColorFactory extends ConstantState<ComplexColor> {
503dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        private final GradientColor mSrc;
504dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
505dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        public GradientColorFactory(GradientColor src) {
506dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            mSrc = src;
507dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
508dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
509dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        @Override
510ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette        public @Config int getChangingConfigurations() {
511dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            return mSrc.mChangingConfigurations;
512dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
513dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
514dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        @Override
515dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        public GradientColor newInstance() {
516dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            return mSrc;
517dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
518dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
519dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        @Override
520dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        public GradientColor newInstance(Resources res, Theme theme) {
521dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            return mSrc.obtainForTheme(theme);
522dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
523dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
524dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
525dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
526dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * Returns an appropriately themed gradient color.
527dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     *
528dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * @param t the theme to apply
529dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * @return a copy of the gradient color the theme applied, or the
530dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * gradient itself if there were no unresolved theme
531dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * attributes
532dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * @hide only for resource preloading
533dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
534dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    @Override
535dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    public GradientColor obtainForTheme(Theme t) {
536dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (t == null || !canApplyTheme()) {
537dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            return this;
538dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
539dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
540dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        final GradientColor clone = new GradientColor(this);
541dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        clone.applyTheme(t);
542dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        return clone;
543dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
544dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
5450b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette    /**
5460b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette     * Returns a mask of the configuration parameters for which this gradient
5470b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette     * may change, requiring that it be re-created.
5480b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette     *
5490b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette     * @return a mask of the changing configuration parameters, as defined by
5500b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette     *         {@link android.content.pm.ActivityInfo}
5510b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette     *
5520b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette     * @see android.content.pm.ActivityInfo
5530b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette     */
5540b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette    public int getChangingConfigurations() {
5550b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette        return super.getChangingConfigurations() | mChangingConfigurations;
5560b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette    }
5570b9295d06750dc6da032a2b2092e2c500c65393fAlan Viverette
558dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private void applyTheme(Theme t) {
559dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (mThemeAttrs != null) {
560dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            applyRootAttrsTheme(t);
561dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
562dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        if (mItemsThemeAttrs != null) {
563dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            applyItemsAttrsTheme(t);
564dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        }
565dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        onColorsChange();
566dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
567dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
568dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    private void applyRootAttrsTheme(Theme t) {
569dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.GradientColor);
570dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        // mThemeAttrs will be set to null if if there are no theme attributes in the
571dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        // typed array.
572dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mThemeAttrs = a.extractThemeAttrs(mThemeAttrs);
573dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        // merging the attributes update inside the updateRootElementState().
574dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        updateRootElementState(a);
575dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
576dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        // Account for any configuration changes.
577dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        mChangingConfigurations |= a.getChangingConfigurations();
578dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        a.recycle();
579dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
580dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
581dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
582dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
583dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * Returns whether a theme can be applied to this gradient color, which
584dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * usually indicates that the gradient color has unresolved theme
585dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * attributes.
586dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     *
587dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * @return whether a theme can be applied to this gradient color.
588dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * @hide only for resource preloading
589dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     */
590dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    @Override
591dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    public boolean canApplyTheme() {
592dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        return mThemeAttrs != null || mItemsThemeAttrs != null;
593dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
594dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
595dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu}
596