GradientColor.java revision dbee9bb342cdfaa5155b1918f90262c05e2464cb
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; 20dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.annotation.NonNull; 21dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.annotation.Nullable; 22dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.content.res.Resources.Theme; 23dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 24dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport com.android.internal.R; 25dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport com.android.internal.util.GrowingArrayUtils; 26dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 27dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport org.xmlpull.v1.XmlPullParser; 28dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport org.xmlpull.v1.XmlPullParserException; 29dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 30dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.graphics.LinearGradient; 31dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.graphics.RadialGradient; 32dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.graphics.Shader; 33dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.graphics.SweepGradient; 34dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.graphics.drawable.GradientDrawable; 35dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.util.AttributeSet; 36dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.util.Log; 37dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport android.util.Xml; 38dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 39dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhuimport java.io.IOException; 40dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 41dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 42dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhupublic class GradientColor extends ComplexColor { 43dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private static final String TAG = "GradientColor"; 44dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 45dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private static final boolean DBG_GRADIENT = false; 46dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 47dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** Lazily-created factory for this GradientColor. */ 48dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private GradientColorFactory mFactory; 49dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 50dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private int mChangingConfigurations; 51dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private int mDefaultColor; 52dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 53dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // After parsing all the attributes from XML, this shader is the ultimate result containing 54dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // all the XML information. 55dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private Shader mShader = null; 56dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 57dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // Below are the attributes at the root element <gradient> 58dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private int mGradientType = GradientDrawable.LINEAR_GRADIENT; 59dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 60dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private float mCenterX = 0f; 61dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private float mCenterY = 0f; 62dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 63dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private float mStartX = 0f; 64dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private float mStartY = 0f; 65dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private float mEndX = 0f; 66dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private float mEndY = 0f; 67dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 68dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private int mStartColor = 0; 69dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private int mCenterColor = 0; 70dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private int mEndColor = 0; 71dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private boolean mHasCenterColor = false; 72dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 73dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private float mGradientRadius = 0f; 74dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 75dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // Below are the attributes for the <item> element. 76dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private int[] mItemColors; 77dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private float[] mItemOffsets; 78dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 79dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // Theme attributes for the root and item elements. 80dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private int[] mThemeAttrs; 81dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private int[][] mItemsThemeAttrs; 82dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 83dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private GradientColor() { 84dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 85dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 86dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private GradientColor(GradientColor copy) { 87dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (copy != null) { 88dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mChangingConfigurations = copy.mChangingConfigurations; 89dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mDefaultColor = copy.mDefaultColor; 90dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mShader = copy.mShader; 91dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mGradientType = copy.mGradientType; 92dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mCenterX = copy.mCenterX; 93dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mCenterY = copy.mCenterY; 94dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mStartX = copy.mStartX; 95dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mStartY = copy.mStartY; 96dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mEndX = copy.mEndX; 97dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mEndY = copy.mEndY; 98dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mStartColor = copy.mStartColor; 99dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mCenterColor = copy.mCenterColor; 100dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mEndColor = copy.mEndColor; 101dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mHasCenterColor = copy.mHasCenterColor; 102dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mGradientRadius = copy.mGradientRadius; 103dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 104dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (copy.mItemColors != null) { 105dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mItemColors = copy.mItemColors.clone(); 106dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 107dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (copy.mItemOffsets != null) { 108dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mItemOffsets = copy.mItemOffsets.clone(); 109dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 110dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 111dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (copy.mThemeAttrs != null) { 112dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mThemeAttrs = copy.mThemeAttrs.clone(); 113dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 114dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (copy.mItemsThemeAttrs != null) { 115dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mItemsThemeAttrs = copy.mItemsThemeAttrs.clone(); 116dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 117dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 118dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 119dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 120dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** 121dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Update the root level's attributes, either for inflate or applyTheme. 122dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */ 123dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private void updateRootElementState(TypedArray a) { 124dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // Extract the theme attributes, if any. 125dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mThemeAttrs = a.extractThemeAttrs(); 126dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 127dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mStartX = a.getFloat( 128dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColor_startX, mStartX); 129dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mStartY = a.getFloat( 130dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColor_startY, mStartY); 131dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mEndX = a.getFloat( 132dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColor_endX, mEndX); 133dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mEndY = a.getFloat( 134dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColor_endY, mEndY); 135dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 136dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mCenterX = a.getFloat( 137dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColor_centerX, mCenterX); 138dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mCenterY = a.getFloat( 139dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColor_centerY, mCenterY); 140dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 141dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mGradientType = a.getInt( 142dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColor_type, mGradientType); 143dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 144dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mStartColor = a.getColor( 145dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColor_startColor, mStartColor); 146dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mHasCenterColor |= a.hasValue( 147dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColor_centerColor); 148dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mCenterColor = a.getColor( 149dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColor_centerColor, mCenterColor); 150dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mEndColor = a.getColor( 151dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColor_endColor, mEndColor); 152dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 153dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (DBG_GRADIENT) { 154dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu Log.v(TAG, "hasCenterColor is " + mHasCenterColor); 155dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (mHasCenterColor) { 156dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu Log.v(TAG, "centerColor:" + mCenterColor); 157dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 158dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu Log.v(TAG, "startColor: " + mStartColor); 159dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu Log.v(TAG, "endColor: " + mEndColor); 160dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 161dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 162dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mGradientRadius = a.getFloat(R.styleable.GradientColor_gradientRadius, 163dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mGradientRadius); 164dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 165dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 166dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** 167dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Check if the XML content is valid. 168dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * 169dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * @throws XmlPullParserException if errors were found. 170dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */ 171dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private void validateXmlContent() throws XmlPullParserException { 172dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (mGradientRadius <= 0 173dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu && mGradientType == GradientDrawable.RADIAL_GRADIENT) { 174dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu throw new XmlPullParserException( 175dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu "<gradient> tag requires 'gradientRadius' " 176dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu + "attribute with radial type"); 177dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 178dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 179dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 180dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** 181dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * The shader information will be applied to the native VectorDrawable's path. 182dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * @hide 183dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */ 184dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu public Shader getShader() { 185dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu return mShader; 186dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 187dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 188dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** 189dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * A public method to create GradientColor from a XML resource. 190dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */ 191dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu public static GradientColor createFromXml(Resources r, XmlResourceParser parser, Theme theme) 192dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu throws XmlPullParserException, IOException { 193dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu final AttributeSet attrs = Xml.asAttributeSet(parser); 194dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 195dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu int type; 196dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu while ((type = parser.next()) != XmlPullParser.START_TAG 197dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu && type != XmlPullParser.END_DOCUMENT) { 198dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // Seek parser to start tag. 199dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 200dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 201dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (type != XmlPullParser.START_TAG) { 202dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu throw new XmlPullParserException("No start tag found"); 203dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 204dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 205dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu return createFromXmlInner(r, parser, attrs, theme); 206dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 207dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 208dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** 209dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Create from inside an XML document. Called on a parser positioned at a 210dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * tag in an XML document, tries to create a GradientColor from that tag. 211dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * 212dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * @return A new GradientColor for the current tag. 213dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * @throws XmlPullParserException if the current tag is not <gradient> 214dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */ 215dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu @NonNull 216dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu static GradientColor createFromXmlInner(@NonNull Resources r, 217dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme) 218dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu throws XmlPullParserException, IOException { 219dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu final String name = parser.getName(); 220dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (!name.equals("gradient")) { 221dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu throw new XmlPullParserException( 222dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu parser.getPositionDescription() + ": invalid gradient color tag " + name); 223dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 224dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 225dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu final GradientColor gradientColor = new GradientColor(); 226dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu gradientColor.inflate(r, parser, attrs, theme); 227dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu return gradientColor; 228dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 229dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 230dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** 231dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Fill in this object based on the contents of an XML "gradient" element. 232dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */ 233dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private void inflate(@NonNull Resources r, @NonNull XmlPullParser parser, 234dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu @NonNull AttributeSet attrs, @Nullable Theme theme) 235dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu throws XmlPullParserException, IOException { 236dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu final TypedArray a = Resources.obtainAttributes(r, theme, attrs, R.styleable.GradientColor); 237dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu updateRootElementState(a); 238dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mChangingConfigurations |= a.getChangingConfigurations(); 239dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu a.recycle(); 240dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 241dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // Check correctness and throw exception if errors found. 242dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu validateXmlContent(); 243dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 244dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu inflateChildElements(r, parser, attrs, theme); 245dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 246dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu onColorsChange(); 247dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 248dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 249dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** 250dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Inflates child elements "item"s for each color stop. 251dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * 252dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Note that at root level, we need to save ThemeAttrs for theme applied later. 253dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Here similarly, at each child item, we need to save the theme's attributes, and apply theme 254dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * later as applyItemsAttrsTheme(). 255dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */ 256dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private void inflateChildElements(@NonNull Resources r, @NonNull XmlPullParser parser, 257dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu @NonNull AttributeSet attrs, @NonNull Theme theme) 258dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu throws XmlPullParserException, IOException { 259dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu final int innerDepth = parser.getDepth() + 1; 260dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu int type; 261dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu int depth; 262dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 263dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // Pre-allocate the array with some size, for better performance. 264dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu float[] offsetList = new float[20]; 265dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu int[] colorList = new int[offsetList.length]; 266dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu int[][] themeAttrsList = new int[offsetList.length][]; 267dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 268dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu int listSize = 0; 269dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu boolean hasUnresolvedAttrs = false; 270dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 271dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu && ((depth = parser.getDepth()) >= innerDepth 272dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu || type != XmlPullParser.END_TAG)) { 273dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (type != XmlPullParser.START_TAG) { 274dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu continue; 275dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 276dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (depth > innerDepth || !parser.getName().equals("item")) { 277dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu continue; 278dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 279dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 280dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu final TypedArray a = Resources.obtainAttributes(r, theme, attrs, 281dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColorItem); 282dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu boolean hasColor = a.hasValue(R.styleable.GradientColorItem_color); 283dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu boolean hasOffset = a.hasValue(R.styleable.GradientColorItem_offset); 284dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (!hasColor || !hasOffset) { 285dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu throw new XmlPullParserException( 286dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu parser.getPositionDescription() 287dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu + ": <item> tag requires a 'color' attribute and a 'offset' " 288dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu + "attribute!"); 289dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 290dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 291dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu final int[] themeAttrs = a.extractThemeAttrs(); 292dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu int color = a.getColor(R.styleable.GradientColorItem_color, 0); 293dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu float offset = a.getFloat(R.styleable.GradientColorItem_offset, 0); 294dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 295dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (DBG_GRADIENT) { 296dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu Log.v(TAG, "new item color " + color + " " + Integer.toHexString(color)); 297dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu Log.v(TAG, "offset" + offset); 298dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 299dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mChangingConfigurations |= a.getChangingConfigurations(); 300dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu a.recycle(); 301dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 302dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (themeAttrs != null) { 303dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu hasUnresolvedAttrs = true; 304dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 305dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 306dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu colorList = GrowingArrayUtils.append(colorList, listSize, color); 307dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu offsetList = GrowingArrayUtils.append(offsetList, listSize, offset); 308dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu themeAttrsList = GrowingArrayUtils.append(themeAttrsList, listSize, themeAttrs); 309dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu listSize++; 310dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 311dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (listSize > 0) { 312dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (hasUnresolvedAttrs) { 313dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mItemsThemeAttrs = new int[listSize][]; 314dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu System.arraycopy(themeAttrsList, 0, mItemsThemeAttrs, 0, listSize); 315dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } else { 316dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mItemsThemeAttrs = null; 317dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 318dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 319dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mItemColors = new int[listSize]; 320dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mItemOffsets = new float[listSize]; 321dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu System.arraycopy(colorList, 0, mItemColors, 0, listSize); 322dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu System.arraycopy(offsetList, 0, mItemOffsets, 0, listSize); 323dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 324dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 325dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 326dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** 327dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Apply theme to all the items. 328dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */ 329dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private void applyItemsAttrsTheme(Theme t) { 330dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (mItemsThemeAttrs == null) { 331dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu return; 332dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 333dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 334dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu boolean hasUnresolvedAttrs = false; 335dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 336dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu final int[][] themeAttrsList = mItemsThemeAttrs; 337dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu final int N = themeAttrsList.length; 338dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu for (int i = 0; i < N; i++) { 339dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (themeAttrsList[i] != null) { 340dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu final TypedArray a = t.resolveAttributes(themeAttrsList[i], 341dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu R.styleable.GradientColorItem); 342dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 343dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // Extract the theme attributes, if any, before attempting to 344dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // read from the typed array. This prevents a crash if we have 345dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // unresolved attrs. 346dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu themeAttrsList[i] = a.extractThemeAttrs(themeAttrsList[i]); 347dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (themeAttrsList[i] != null) { 348dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu hasUnresolvedAttrs = true; 349dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 350dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 351dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mItemColors[i] = a.getColor(R.styleable.GradientColorItem_color, mItemColors[i]); 352dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mItemOffsets[i] = a.getFloat(R.styleable.GradientColorItem_offset, mItemOffsets[i]); 353dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (DBG_GRADIENT) { 354dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu Log.v(TAG, "applyItemsAttrsTheme Colors[i] " + i + " " + 355dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu Integer.toHexString(mItemColors[i])); 356dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu Log.v(TAG, "Offsets[i] " + i + " " + mItemOffsets[i]); 357dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 358dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 359dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // Account for any configuration changes. 360dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mChangingConfigurations |= a.getChangingConfigurations(); 361dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 362dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu a.recycle(); 363dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 364dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 365dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 366dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (!hasUnresolvedAttrs) { 367dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mItemsThemeAttrs = null; 368dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 369dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 370dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 371dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private void onColorsChange() { 372dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu int[] tempColors = null; 373dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu float[] tempOffsets = null; 374dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 375dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (mItemColors != null) { 376dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu int length = mItemColors.length; 377dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempColors = new int[length]; 378dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempOffsets = new float[length]; 379dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 380dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu for (int i = 0; i < length; i++) { 381dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempColors[i] = mItemColors[i]; 382dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempOffsets[i] = mItemOffsets[i]; 383dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 384dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } else { 385dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (mHasCenterColor) { 386dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempColors = new int[3]; 387dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempColors[0] = mStartColor; 388dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempColors[1] = mCenterColor; 389dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempColors[2] = mEndColor; 390dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 391dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempOffsets = new float[3]; 392dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempOffsets[0] = 0.0f; 393dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // Since 0.5f is default value, try to take the one that isn't 0.5f 394dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempOffsets[1] = 0.5f; 395dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempOffsets[2] = 1f; 396dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } else { 397dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempColors = new int[2]; 398dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempColors[0] = mStartColor; 399dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempColors[1] = mEndColor; 400dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 401dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 402dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (tempColors.length < 2) { 403dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu Log.w(TAG, "<gradient> tag requires 2 color values specified!" + tempColors.length 404dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu + " " + tempColors); 405dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 406dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 407dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (mGradientType == GradientDrawable.LINEAR_GRADIENT) { 408dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mShader = new LinearGradient(mStartX, mStartY, mEndX, mEndY, tempColors, tempOffsets, 409dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu Shader.TileMode.CLAMP); 410dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } else { 411dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (mGradientType == GradientDrawable.RADIAL_GRADIENT) { 412dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mShader = new RadialGradient(mCenterX, mCenterY, mGradientRadius, tempColors, 413dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu tempOffsets, Shader.TileMode.CLAMP); 414dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } else { 415dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mShader = new SweepGradient(mCenterX, mCenterY, tempColors, tempOffsets); 416dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 417dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 418dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mDefaultColor = tempColors[0]; 419dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 420dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 421dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** 422dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * For Gradient color, the default color is not very useful, since the gradient will override 423dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * the color information anyway. 424dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */ 425dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu @Override 426dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu @ColorInt 427dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu public int getDefaultColor() { 428dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu return mDefaultColor; 429dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 430dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 431dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** 432dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Similar to ColorStateList, setup constant state and its factory. 433dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * @hide only for resource preloading 434dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */ 435dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu @Override 436dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu public ConstantState<ComplexColor> getConstantState() { 437dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (mFactory == null) { 438dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mFactory = new GradientColorFactory(this); 439dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 440dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu return mFactory; 441dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 442dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 443dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private static class GradientColorFactory extends ConstantState<ComplexColor> { 444dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private final GradientColor mSrc; 445dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 446dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu public GradientColorFactory(GradientColor src) { 447dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mSrc = src; 448dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 449dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 450dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu @Override 451dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu public int getChangingConfigurations() { 452dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu return mSrc.mChangingConfigurations; 453dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 454dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 455dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu @Override 456dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu public GradientColor newInstance() { 457dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu return mSrc; 458dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 459dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 460dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu @Override 461dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu public GradientColor newInstance(Resources res, Theme theme) { 462dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu return mSrc.obtainForTheme(theme); 463dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 464dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 465dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 466dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** 467dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Returns an appropriately themed gradient color. 468dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * 469dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * @param t the theme to apply 470dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * @return a copy of the gradient color the theme applied, or the 471dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * gradient itself if there were no unresolved theme 472dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * attributes 473dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * @hide only for resource preloading 474dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */ 475dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu @Override 476dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu public GradientColor obtainForTheme(Theme t) { 477dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (t == null || !canApplyTheme()) { 478dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu return this; 479dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 480dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 481dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu final GradientColor clone = new GradientColor(this); 482dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu clone.applyTheme(t); 483dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu return clone; 484dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 485dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 486dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private void applyTheme(Theme t) { 487dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (mThemeAttrs != null) { 488dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu applyRootAttrsTheme(t); 489dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 490dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu if (mItemsThemeAttrs != null) { 491dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu applyItemsAttrsTheme(t); 492dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 493dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu onColorsChange(); 494dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 495dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 496dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu private void applyRootAttrsTheme(Theme t) { 497dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.GradientColor); 498dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // mThemeAttrs will be set to null if if there are no theme attributes in the 499dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // typed array. 500dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mThemeAttrs = a.extractThemeAttrs(mThemeAttrs); 501dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // merging the attributes update inside the updateRootElementState(). 502dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu updateRootElementState(a); 503dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 504dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu // Account for any configuration changes. 505dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu mChangingConfigurations |= a.getChangingConfigurations(); 506dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu a.recycle(); 507dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 508dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 509dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 510dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu /** 511dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * Returns whether a theme can be applied to this gradient color, which 512dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * usually indicates that the gradient color has unresolved theme 513dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * attributes. 514dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * 515dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * @return whether a theme can be applied to this gradient color. 516dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu * @hide only for resource preloading 517dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu */ 518dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu @Override 519dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu public boolean canApplyTheme() { 520dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu return mThemeAttrs != null || mItemsThemeAttrs != null; 521dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu } 522dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu 523dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu} 524