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