GradientDrawable.java revision 6a49ddef62865c1b245ad60a13c334f0ffaf1a5f
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics.drawable; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1980756e38882720860db52f1fcc21fa1505a02abfTor Norbyeimport android.annotation.ColorInt; 20519494e207322581075c8ea884fde9d33bb9209eAlan Viveretteimport android.content.res.ColorStateList; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 2352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport android.content.res.Resources.Theme; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas; 254d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viveretteimport android.graphics.Color; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.ColorFilter; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.DashPathEffect; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.LinearGradient; 29b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craikimport android.graphics.Outline; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Paint; 31519494e207322581075c8ea884fde9d33bb9209eAlan Viveretteimport android.graphics.Path; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 3343027b7bca554818cc4223389747d661819d5706Alan Viveretteimport android.graphics.PorterDuff; 3443027b7bca554818cc4223389747d661819d5706Alan Viveretteimport android.graphics.PorterDuffColorFilter; 35519494e207322581075c8ea884fde9d33bb9209eAlan Viveretteimport android.graphics.RadialGradient; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.RectF; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Shader; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.SweepGradient; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.TypedValue; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport com.android.internal.R; 4552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 5217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * A Drawable with a color gradient for buttons, backgrounds, etc. 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 54dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * <p>It can be defined in an XML file with the <code><shape></code> element. For more 55dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * information, see the guide to <a 56dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.</p> 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_visible 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_shape 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_innerRadiusRatio 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_innerRadius 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_thicknessRatio 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_thickness 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_useLevel 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableSize_width 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableSize_height 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_startColor 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_centerColor 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_endColor 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_useLevel 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_angle 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_type 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_centerX 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_centerY 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_gradientRadius 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableSolid_color 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableStroke_width 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableStroke_color 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableStroke_dashWidth 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableStroke_dashGap 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawablePadding_left 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawablePadding_top 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawablePadding_right 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawablePadding_bottom 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class GradientDrawable extends Drawable { 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shape is a rectangle, possibly with rounded corners 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RECTANGLE = 0; 9117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shape is an ellipse 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public static final int OVAL = 1; 9617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shape is a line 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int LINE = 2; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shape is a ring. 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RING = 3; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gradient is linear (default.) 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int LINEAR_GRADIENT = 0; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gradient is circular. 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RADIAL_GRADIENT = 1; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gradient is a sweep. 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SWEEP_GRADIENT = 2; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 122b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette /** Radius is in pixels. */ 123b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette private static final int RADIUS_TYPE_PIXELS = 0; 124b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 125b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette /** Radius is a fraction of the base size. */ 126b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette private static final int RADIUS_TYPE_FRACTION = 1; 127b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 128b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette /** Radius is a fraction of the bounds size. */ 129b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette private static final int RADIUS_TYPE_FRACTION_PARENT = 2; 130b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 13152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private static final float DEFAULT_INNER_RADIUS_RATIO = 3.0f; 13252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private static final float DEFAULT_THICKNESS_RATIO = 9.0f; 13352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GradientState mGradientState; 13517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1366a49ddef62865c1b245ad60a13c334f0ffaf1a5fChris Craik private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Rect mPadding; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Paint mStrokePaint; // optional, set by the caller 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ColorFilter mColorFilter; // optional, set by the caller 14043027b7bca554818cc4223389747d661819d5706Alan Viverette private PorterDuffColorFilter mTintFilter; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mAlpha = 0xFF; // modified by the caller 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Path mPath = new Path(); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final RectF mRect = new RectF(); 145e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Paint mLayerPaint; // internal, used if we use saveLayer() 14745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private boolean mGradientIsDirty; 148684385ddde2ac0c26de0862390ad713aff3fb149Romain Guy private boolean mMutated; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Path mRingPath; 1501041aded2df45094c36831028245fb7c5e9b67b7Romain Guy private boolean mPathIsDirty = true; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1523aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase /** Current gradient radius, valid when {@link #mGradientIsDirty} is false. */ 153861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette private float mGradientRadius; 154861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Controls how the gradient is oriented relative to the drawable's bounds 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public enum Orientation { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the top to the bottom */ 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TOP_BOTTOM, 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the top-right to the bottom-left */ 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TR_BL, 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the right to the left */ 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RIGHT_LEFT, 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the bottom-right to the top-left */ 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BR_TL, 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the bottom to the top */ 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BOTTOM_TOP, 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the bottom-left to the top-right */ 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BL_TR, 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the left to the right */ 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LEFT_RIGHT, 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the top-left to the bottom-right */ 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TL_BR, 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GradientDrawable() { 17845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette this(new GradientState(Orientation.TOP_BOTTOM, null), null); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new gradient drawable given an orientation and an array 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of colors for the gradient. 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18580756e38882720860db52f1fcc21fa1505a02abfTor Norbye public GradientDrawable(Orientation orientation, @ColorInt int[] colors) { 18645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette this(new GradientState(orientation, colors), null); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean getPadding(Rect padding) { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPadding != null) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project padding.set(mPadding); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.getPadding(padding); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2008bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Specify radii for each of the 4 corners. For each corner, the array 2018bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * contains 2 values, <code>[X_radius, Y_radius]</code>. The corners are ordered 2028bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * top-left, top-right, bottom-right, bottom-left. This property 2038bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * is honored only when the shape is of type {@link #RECTANGLE}.</p> 2048bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 2058bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 2068bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 2078bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 2088bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param radii 4 pairs of X and Y radius for each corner, specified in pixels. 2098bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * The length of this array must be >= 8 2108bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 2118bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 2128bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #setCornerRadii(float[]) 2138bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #setShape(int) 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setCornerRadii(float[] radii) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.setCornerRadii(radii); 2171041aded2df45094c36831028245fb7c5e9b67b7Romain Guy mPathIsDirty = true; 2189891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2228bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Specify radius for the corners of the gradient. If this is > 0, then the 2238bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * drawable is drawn in a round-rectangle, rather than a rectangle. This property 2248bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * is honored only when the shape is of type {@link #RECTANGLE}.</p> 2258bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 2268bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 2278bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 2288bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 2298bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param radius The radius in pixels of the corners of the rectangle shape 2308bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 2318bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 2328bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #setCornerRadii(float[]) 23317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setShape(int) 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setCornerRadius(float radius) { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.setCornerRadius(radius); 2371041aded2df45094c36831028245fb7c5e9b67b7Romain Guy mPathIsDirty = true; 2389891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2408bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2428bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Set the stroke width and color for the drawable. If width is zero, 2438bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * then no stroke is drawn.</p> 2448bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 2458bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 2468bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 2478bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 2488bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param width The width in pixels of the stroke 2498bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param color The color of the stroke 2508bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 2518bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 25217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setStroke(int, int, float, float) 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 25480756e38882720860db52f1fcc21fa1505a02abfTor Norbye public void setStroke(int width, @ColorInt int color) { 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setStroke(width, color, 0, 0); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2578bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 2588bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 259a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * <p>Set the stroke width and color state list for the drawable. If width 260a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * is zero, then no stroke is drawn.</p> 261a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * <p><strong>Note</strong>: changing this property will affect all instances 262a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * of a drawable loaded from a resource. It is recommended to invoke 263a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * {@link #mutate()} before changing this property.</p> 264a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * 265a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @param width The width in pixels of the stroke 266a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @param colorStateList The color state list of the stroke 267a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * 268a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @see #mutate() 269a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @see #setStroke(int, ColorStateList, float, float) 270a211dd28b93473c452d68432c602d5209b01c178Alan Viverette */ 271a211dd28b93473c452d68432c602d5209b01c178Alan Viverette public void setStroke(int width, ColorStateList colorStateList) { 272a211dd28b93473c452d68432c602d5209b01c178Alan Viverette setStroke(width, colorStateList, 0, 0); 273a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 274a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 275a211dd28b93473c452d68432c602d5209b01c178Alan Viverette /** 2768bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Set the stroke width and color for the drawable. If width is zero, 2778bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * then no stroke is drawn. This method can also be used to dash the stroke.</p> 2788bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 2798bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 2808bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 2818bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 2828bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param width The width in pixels of the stroke 2838bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param color The color of the stroke 28417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes 2858bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param dashGap The gap in pixels between dashes 2868bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 2878bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 28817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setStroke(int, int) 2898bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 29080756e38882720860db52f1fcc21fa1505a02abfTor Norbye public void setStroke(int width, @ColorInt int color, float dashWidth, float dashGap) { 29140df78153987409dbf299b84da9784b69029e184Alan Viverette mGradientState.setStroke(width, ColorStateList.valueOf(color), dashWidth, dashGap); 292a211dd28b93473c452d68432c602d5209b01c178Alan Viverette setStrokeInternal(width, color, dashWidth, dashGap); 293a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 295a211dd28b93473c452d68432c602d5209b01c178Alan Viverette /** 296a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * <p>Set the stroke width and color state list for the drawable. If width 297a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * is zero, then no stroke is drawn. This method can also be used to dash 298a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * the stroke.</p> 299a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * <p><strong>Note</strong>: changing this property will affect all instances 300a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * of a drawable loaded from a resource. It is recommended to invoke 301a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * {@link #mutate()} before changing this property.</p> 302a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * 303a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @param width The width in pixels of the stroke 304a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @param colorStateList The color state list of the stroke 305a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes 306a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @param dashGap The gap in pixels between dashes 307a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * 308a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @see #mutate() 309a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @see #setStroke(int, ColorStateList) 310a211dd28b93473c452d68432c602d5209b01c178Alan Viverette */ 311a211dd28b93473c452d68432c602d5209b01c178Alan Viverette public void setStroke( 312a211dd28b93473c452d68432c602d5209b01c178Alan Viverette int width, ColorStateList colorStateList, float dashWidth, float dashGap) { 31340df78153987409dbf299b84da9784b69029e184Alan Viverette mGradientState.setStroke(width, colorStateList, dashWidth, dashGap); 31440df78153987409dbf299b84da9784b69029e184Alan Viverette final int color; 3157c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette if (colorStateList == null) { 31640df78153987409dbf299b84da9784b69029e184Alan Viverette color = Color.TRANSPARENT; 3177c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette } else { 3187c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette final int[] stateSet = getState(); 31940df78153987409dbf299b84da9784b69029e184Alan Viverette color = colorStateList.getColorForState(stateSet, 0); 3207c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette } 32140df78153987409dbf299b84da9784b69029e184Alan Viverette setStrokeInternal(width, color, dashWidth, dashGap); 322a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 323a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 324a211dd28b93473c452d68432c602d5209b01c178Alan Viverette private void setStrokeInternal(int width, int color, float dashWidth, float dashGap) { 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStrokePaint == null) { 3266a49ddef62865c1b245ad60a13c334f0ffaf1a5fChris Craik mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setStyle(Paint.Style.STROKE); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setStrokeWidth(width); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setColor(color); 33117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DashPathEffect e = null; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dashWidth > 0) { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e = new DashPathEffect(new float[] { dashWidth, dashGap }, 0); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setPathEffect(e); 3379891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3398bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 3408bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 3418bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 3428bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Sets the size of the shape drawn by this drawable.</p> 3438bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 3448bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 3458bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 3468bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 3478bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param width The width of the shape used by this drawable 3488bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param height The height of the shape used by this drawable 3498bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 3508bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 3518bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #setGradientType(int) 3528bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setSize(int width, int height) { 3541041aded2df45094c36831028245fb7c5e9b67b7Romain Guy mGradientState.setSize(width, height); 3551041aded2df45094c36831028245fb7c5e9b67b7Romain Guy mPathIsDirty = true; 3569891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3588bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 3598bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 3608bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Sets the type of shape used to draw the gradient.</p> 3618bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 3628bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 3638bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 3648bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 3658bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param shape The desired shape for this drawable: {@link #LINE}, 3668bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #OVAL}, {@link #RECTANGLE} or {@link #RING} 3678bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 3688bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 3698bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setShape(int shape) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRingPath = null; 3721041aded2df45094c36831028245fb7c5e9b67b7Romain Guy mPathIsDirty = true; 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.setShape(shape); 3749891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3778bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 3788bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Sets the type of gradient used by this drawable..</p> 3798bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 3808bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 3818bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 3828bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 3838bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param gradient The type of the gradient: {@link #LINEAR_GRADIENT}, 3848bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #RADIAL_GRADIENT} or {@link #SWEEP_GRADIENT} 3858bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 3868bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 3878bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGradientType(int gradient) { 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.setGradientType(gradient); 3903aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 3919891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3948bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 39517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * <p>Sets the center location of the gradient. The radius is honored only when 3968bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * the gradient type is set to {@link #RADIAL_GRADIENT} or {@link #SWEEP_GRADIENT}.</p> 3978bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 3988bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 3998bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 4008bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4018bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param x The x coordinate of the gradient's center 4028bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param y The y coordinate of the gradient's center 4038bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4048bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 4058bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #setGradientType(int) 4068bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGradientCenter(float x, float y) { 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.setGradientCenter(x, y); 4093aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 4109891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4138bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 4148bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Sets the radius of the gradient. The radius is honored only when the 4158bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * gradient type is set to {@link #RADIAL_GRADIENT}.</p> 4168bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 4178bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 4188bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 4198bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4208bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param gradientRadius The radius of the gradient in pixels 4218bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4228bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 42317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setGradientType(int) 4248bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGradientRadius(float gradientRadius) { 426861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette mGradientState.setGradientRadius(gradientRadius, TypedValue.COMPLEX_UNIT_PX); 4273aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 4289891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4318bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 432861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette * Returns the radius of the gradient in pixels. The radius is valid only 433861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette * when the gradient type is set to {@link #RADIAL_GRADIENT}. 434861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette * 435861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette * @return Radius in pixels. 436861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette */ 437861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette public float getGradientRadius() { 438861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette if (mGradientState.mGradient != RADIAL_GRADIENT) { 439861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette return 0; 440861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette } 441861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette 442861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette ensureValidRect(); 443861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette return mGradientRadius; 444861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette } 445861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette 446861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette /** 4478bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Sets whether or not this drawable will honor its <code>level</code> 4488bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * property.</p> 4498bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 4508bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 4518bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 4528bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4538bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param useLevel True if this drawable should honor its level, false otherwise 4548bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4558bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 45617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setLevel(int) 45717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #getLevel() 4588bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setUseLevel(boolean useLevel) { 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.mUseLevel = useLevel; 4613aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 4629891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 46417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int modulateAlpha(int alpha) { 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int scale = mAlpha + (mAlpha >> 7); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return alpha * scale >> 8; 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4708bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 4718bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * Returns the orientation of the gradient defined in this drawable. 4728bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 4738bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy public Orientation getOrientation() { 4748bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy return mGradientState.mOrientation; 4758bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy } 4768bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 4778bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 4788bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Changes the orientation of the gradient defined in this drawable.</p> 4798bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing orientation will affect all instances 4808bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 4818bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing the orientation.</p> 48217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * 4838bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param orientation The desired orientation (angle) of the gradient 48417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * 48517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #mutate() 4868bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 4878bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy public void setOrientation(Orientation orientation) { 4888bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy mGradientState.mOrientation = orientation; 4893aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 4908bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy invalidateSelf(); 4918bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy } 4928bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 4938bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 494e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * Sets the colors used to draw the gradient. 495e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * <p> 496e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * Each color is specified as an ARGB integer and the array must contain at 497e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * least 2 colors. 498e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * <p> 499e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * <strong>Note</strong>: changing colors will affect all instances of a 500e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * drawable loaded from a resource. It is recommended to invoke 501e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * {@link #mutate()} before changing the colors. 5028bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 503e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * @param colors an array containing 2 or more ARGB colors 5048bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 50517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setColor(int) 5068bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 50780756e38882720860db52f1fcc21fa1505a02abfTor Norbye public void setColors(@ColorInt int[] colors) { 508e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientState.setGradientColors(colors); 5093aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 5108bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy invalidateSelf(); 5118bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy } 5128bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 51416f1d81d47beb1e04504a76de66e2919dde08c33Alan Viverette public void draw(Canvas canvas) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!ensureValidRect()) { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // nothing to draw 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remember the alpha values, in case we temporarily overwrite them 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when we modulate them with mAlpha 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int prevFillAlpha = mFillPaint.getAlpha(); 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int prevStrokeAlpha = mStrokePaint != null ? mStrokePaint.getAlpha() : 0; 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the modulate alpha values 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int currFillAlpha = modulateAlpha(prevFillAlpha); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int currStrokeAlpha = modulateAlpha(prevStrokeAlpha); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 528e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint != null && 529e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy mStrokePaint.getStrokeWidth() > 0; 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean haveFill = currFillAlpha > 0; 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final GradientState st = mGradientState; 53243027b7bca554818cc4223389747d661819d5706Alan Viverette final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mTintFilter; 53343027b7bca554818cc4223389747d661819d5706Alan Viverette 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* we need a layer iff we're drawing both a fill and stroke, and the 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stroke is non-opaque, and our shapetype actually supports 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fill+stroke. Otherwise we can just draw the stroke (if any) on top 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project of the fill (if any) without worrying about blending artifacts. 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 53943027b7bca554818cc4223389747d661819d5706Alan Viverette final boolean useLayer = haveStroke && haveFill && st.mShape != LINE && 54043027b7bca554818cc4223389747d661819d5706Alan Viverette currStrokeAlpha < 255 && (mAlpha < 255 || colorFilter != null); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Drawing with a layer is slower than direct drawing, but it 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allows us to apply paint effects like alpha and colorfilter to 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project the result of multiple separate draws. In our case, if the user 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asks for a non-opaque alpha value (via setAlpha), and we're 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stroking, then we need to apply the alpha AFTER we've drawn 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project both the fill and the stroke. 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (useLayer) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLayerPaint == null) { 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayerPaint = new Paint(); 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 55307c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mLayerPaint.setDither(st.mDither); 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayerPaint.setAlpha(mAlpha); 55543027b7bca554818cc4223389747d661819d5706Alan Viverette mLayerPaint.setColorFilter(colorFilter); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float rad = mStrokePaint.getStrokeWidth(); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.saveLayer(mRect.left - rad, mRect.top - rad, 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRect.right + rad, mRect.bottom + rad, 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayerPaint, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't perform the filter in our individual paints 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // since the layer will do it for us 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setColorFilter(null); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setColorFilter(null); 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* if we're not using a layer, apply the dither/filter to our 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project individual paints 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setAlpha(currFillAlpha); 57107c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mFillPaint.setDither(st.mDither); 57243027b7bca554818cc4223389747d661819d5706Alan Viverette mFillPaint.setColorFilter(colorFilter); 573e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (colorFilter != null && st.mSolidColors == null) { 574813680780f365648b39873fa26dfae0123d51aedChet Haase mFillPaint.setColor(mAlpha << 24); 57541c769d9a8858ad20b0a6ed942a1cea19ba59d2dRomain Guy } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setAlpha(currStrokeAlpha); 57807c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mStrokePaint.setDither(st.mDither); 57943027b7bca554818cc4223389747d661819d5706Alan Viverette mStrokePaint.setColorFilter(colorFilter); 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 582e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (st.mShape) { 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RECTANGLE: 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st.mRadiusArray != null) { 586e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik buildPathIfDirty(); 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawPath(mPath, mFillPaint); 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawPath(mPath, mStrokePaint); 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 59161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy } else if (st.mRadius > 0.0f) { 5924e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed // since the caller is only giving us 1 value, we will force 5934e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed // it to be square if the rect is too small in one dimension 5944e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed // to show it. If we did nothing, Skia would clamp the rad 59561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy // independently along each axis, giving us a thin ellipse 5964e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed // if the rect were very wide but not very tall 597b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik float rad = Math.min(st.mRadius, 598b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik Math.min(mRect.width(), mRect.height()) * 0.5f); 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawRoundRect(mRect, rad, rad, mFillPaint); 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawRoundRect(mRect, rad, rad, mStrokePaint); 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 60361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy } else { 60443027b7bca554818cc4223389747d661819d5706Alan Viverette if (mFillPaint.getColor() != 0 || colorFilter != null || 605cf8675ee176a375f873792684d38a47f78348dffRomain Guy mFillPaint.getShader() != null) { 606cf8675ee176a375f873792684d38a47f78348dffRomain Guy canvas.drawRect(mRect, mFillPaint); 607cf8675ee176a375f873792684d38a47f78348dffRomain Guy } 60861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy if (haveStroke) { 60961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy canvas.drawRect(mRect, mStrokePaint); 61061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy } 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case OVAL: 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawOval(mRect, mFillPaint); 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawOval(mRect, mStrokePaint); 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LINE: { 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RectF r = mRect; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = r.centerY(); 62271b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette if (haveStroke) { 62371b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette canvas.drawLine(r.left, y, r.right, y, mStrokePaint); 62471b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette } 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RING: 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Path path = buildRing(st); 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawPath(path, mFillPaint); 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawPath(path, mStrokePaint); 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 63517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (useLayer) { 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.restore(); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setAlpha(prevFillAlpha); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setAlpha(prevStrokeAlpha); 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 645e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 646e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik private void buildPathIfDirty() { 647e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik final GradientState st = mGradientState; 6483aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase if (mPathIsDirty) { 6493aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase ensureValidRect(); 650e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik mPath.reset(); 651e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik mPath.addRoundRect(mRect, st.mRadiusArray, Path.Direction.CW); 6523aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mPathIsDirty = false; 653e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik } 654e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik } 655e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Path buildRing(GradientState st) { 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRingPath != null && (!st.mUseLevelForShape || !mPathIsDirty)) return mRingPath; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPathIsDirty = false; 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float sweep = st.mUseLevelForShape ? (360.0f * getLevel() / 10000.0f) : 360f; 66117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RectF bounds = new RectF(mRect); 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = bounds.width() / 2.0f; 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = bounds.height() / 2.0f; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float thickness = st.mThickness != -1 ? 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st.mThickness : bounds.width() / st.mThicknessRatio; 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // inner radius 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float radius = st.mInnerRadius != -1 ? 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st.mInnerRadius : bounds.width() / st.mInnerRadiusRatio; 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RectF innerBounds = new RectF(bounds); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project innerBounds.inset(x - radius, y - radius); 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds = new RectF(innerBounds); 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds.inset(-thickness, -thickness); 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRingPath == null) { 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRingPath = new Path(); 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 682b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik mRingPath.reset(); 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Path ringPath = mRingPath; 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // arcTo treats the sweep angle mod 360, so check for that, since we 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // think 360 means draw the entire oval 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sweep < 360 && sweep > -360) { 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.setFillType(Path.FillType.EVEN_ODD); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // inner top 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.moveTo(x + radius, y); 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // outer top 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.lineTo(x + radius + thickness, y); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // outer arc 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.arcTo(bounds, 0.0f, sweep, false); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // inner arc 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.arcTo(innerBounds, sweep, -sweep, false); 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.close(); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // add the entire ovals 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.addOval(bounds, Path.Direction.CW); 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.addOval(innerBounds, Path.Direction.CCW); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ringPath; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7088bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 709519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * <p>Changes this drawable to use a single color instead of a gradient.</p> 710e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy * <p><strong>Note</strong>: changing color will affect all instances 7118bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 712e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy * {@link #mutate()} before changing the color.</p> 7138bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 7148bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param argb The color used to fill the shape 7158bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 7168bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 71717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setColors(int[]) 7188bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 71980756e38882720860db52f1fcc21fa1505a02abfTor Norbye public void setColor(@ColorInt int argb) { 720e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientState.setSolidColors(ColorStateList.valueOf(argb)); 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setColor(argb); 7229891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 725519494e207322581075c8ea884fde9d33bb9209eAlan Viverette /** 726519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * Changes this drawable to use a single color state list instead of a 7277c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette * gradient. Calling this method with a null argument will clear the color 7287c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette * and is equivalent to calling {@link #setColor(int)} with the argument 7297c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette * {@link Color#TRANSPARENT}. 730519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * <p> 731519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * <strong>Note</strong>: changing color will affect all instances of a 732519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * drawable loaded from a resource. It is recommended to invoke 733519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * {@link #mutate()} before changing the color.</p> 734519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * 735519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * @param colorStateList The color state list used to fill the shape 736519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * @see #mutate() 737519494e207322581075c8ea884fde9d33bb9209eAlan Viverette */ 738519494e207322581075c8ea884fde9d33bb9209eAlan Viverette public void setColor(ColorStateList colorStateList) { 739e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientState.setSolidColors(colorStateList); 74040df78153987409dbf299b84da9784b69029e184Alan Viverette final int color; 7417c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette if (colorStateList == null) { 74240df78153987409dbf299b84da9784b69029e184Alan Viverette color = Color.TRANSPARENT; 7437c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette } else { 74440df78153987409dbf299b84da9784b69029e184Alan Viverette final int[] stateSet = getState(); 74540df78153987409dbf299b84da9784b69029e184Alan Viverette color = colorStateList.getColorForState(stateSet, 0); 7467c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette } 74740df78153987409dbf299b84da9784b69029e184Alan Viverette mFillPaint.setColor(color); 74840df78153987409dbf299b84da9784b69029e184Alan Viverette invalidateSelf(); 749519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 750519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 751519494e207322581075c8ea884fde9d33bb9209eAlan Viverette @Override 75212b97f5d2b15194ed6673c9838b13c8312157709Alan Viverette protected boolean onStateChange(int[] stateSet) { 753a211dd28b93473c452d68432c602d5209b01c178Alan Viverette boolean invalidateSelf = false; 754a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 755a211dd28b93473c452d68432c602d5209b01c178Alan Viverette final GradientState s = mGradientState; 756e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final ColorStateList solidColors = s.mSolidColors; 757e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (solidColors != null) { 758e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int newColor = solidColors.getColorForState(stateSet, 0); 759519494e207322581075c8ea884fde9d33bb9209eAlan Viverette final int oldColor = mFillPaint.getColor(); 760519494e207322581075c8ea884fde9d33bb9209eAlan Viverette if (oldColor != newColor) { 761519494e207322581075c8ea884fde9d33bb9209eAlan Viverette mFillPaint.setColor(newColor); 762616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette invalidateSelf = true; 763a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 764a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 765a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 766616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette final Paint strokePaint = mStrokePaint; 767616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette if (strokePaint != null) { 768e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final ColorStateList strokeColors = s.mStrokeColors; 769e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (strokeColors != null) { 770e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int newColor = strokeColors.getColorForState(stateSet, 0); 771e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int oldColor = strokePaint.getColor(); 772e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (oldColor != newColor) { 773e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette strokePaint.setColor(newColor); 774616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette invalidateSelf = true; 775616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette } 776519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 777519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 778519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 77943027b7bca554818cc4223389747d661819d5706Alan Viverette if (s.mTint != null && s.mTintMode != null) { 78043027b7bca554818cc4223389747d661819d5706Alan Viverette mTintFilter = updateTintFilter(mTintFilter, s.mTint, s.mTintMode); 78143027b7bca554818cc4223389747d661819d5706Alan Viverette invalidateSelf = true; 78243027b7bca554818cc4223389747d661819d5706Alan Viverette } 78343027b7bca554818cc4223389747d661819d5706Alan Viverette 784a211dd28b93473c452d68432c602d5209b01c178Alan Viverette if (invalidateSelf) { 785a211dd28b93473c452d68432c602d5209b01c178Alan Viverette invalidateSelf(); 786a211dd28b93473c452d68432c602d5209b01c178Alan Viverette return true; 787a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 788a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 789a211dd28b93473c452d68432c602d5209b01c178Alan Viverette return false; 790519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 791519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 792519494e207322581075c8ea884fde9d33bb9209eAlan Viverette @Override 793519494e207322581075c8ea884fde9d33bb9209eAlan Viverette public boolean isStateful() { 794a211dd28b93473c452d68432c602d5209b01c178Alan Viverette final GradientState s = mGradientState; 795a211dd28b93473c452d68432c602d5209b01c178Alan Viverette return super.isStateful() 796e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette || (s.mSolidColors != null && s.mSolidColors.isStateful()) 797e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette || (s.mStrokeColors != null && s.mStrokeColors.isStateful()) 79843027b7bca554818cc4223389747d661819d5706Alan Viverette || (s.mTint != null && s.mTint.isStateful()); 799519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 800519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 803e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return super.getChangingConfigurations() | mGradientState.getChangingConfigurations(); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8058bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlpha(int alpha) { 8089891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (alpha != mAlpha) { 8099891e1fce5f29d0421d34aa481037417bd70853dChet Haase mAlpha = alpha; 8109891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 8119891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 815b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase public int getAlpha() { 816b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase return mAlpha; 817b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase } 818b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase 819b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase @Override 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDither(boolean dither) { 82107c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette if (dither != mGradientState.mDither) { 82207c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mGradientState.mDither = dither; 8239891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 8249891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 828f4c068b72e2dee2e6944488ef00b64c93217d7e8Alan Viverette public boolean getDither() { 829f4c068b72e2dee2e6944488ef00b64c93217d7e8Alan Viverette return mGradientState.mDither; 830f4c068b72e2dee2e6944488ef00b64c93217d7e8Alan Viverette } 831f4c068b72e2dee2e6944488ef00b64c93217d7e8Alan Viverette 832f4c068b72e2dee2e6944488ef00b64c93217d7e8Alan Viverette @Override 83338b5f597de96cd892add9017dc810212f549bf68John Spurlock public ColorFilter getColorFilter() { 83438b5f597de96cd892add9017dc810212f549bf68John Spurlock return mColorFilter; 83538b5f597de96cd892add9017dc810212f549bf68John Spurlock } 83638b5f597de96cd892add9017dc810212f549bf68John Spurlock 83738b5f597de96cd892add9017dc810212f549bf68John Spurlock @Override 838bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik public void setColorFilter(ColorFilter colorFilter) { 839bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik if (colorFilter != mColorFilter) { 840bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik mColorFilter = colorFilter; 8419891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 8429891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 84643027b7bca554818cc4223389747d661819d5706Alan Viverette public void setTintList(ColorStateList tint) { 84743027b7bca554818cc4223389747d661819d5706Alan Viverette mGradientState.mTint = tint; 84843027b7bca554818cc4223389747d661819d5706Alan Viverette mTintFilter = updateTintFilter(mTintFilter, tint, mGradientState.mTintMode); 84943027b7bca554818cc4223389747d661819d5706Alan Viverette invalidateSelf(); 85043027b7bca554818cc4223389747d661819d5706Alan Viverette } 85143027b7bca554818cc4223389747d661819d5706Alan Viverette 85243027b7bca554818cc4223389747d661819d5706Alan Viverette @Override 85343027b7bca554818cc4223389747d661819d5706Alan Viverette public void setTintMode(PorterDuff.Mode tintMode) { 85443027b7bca554818cc4223389747d661819d5706Alan Viverette mGradientState.mTintMode = tintMode; 85543027b7bca554818cc4223389747d661819d5706Alan Viverette mTintFilter = updateTintFilter(mTintFilter, mGradientState.mTint, tintMode); 85643027b7bca554818cc4223389747d661819d5706Alan Viverette invalidateSelf(); 85743027b7bca554818cc4223389747d661819d5706Alan Viverette } 85843027b7bca554818cc4223389747d661819d5706Alan Viverette 85943027b7bca554818cc4223389747d661819d5706Alan Viverette @Override 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 861888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return (mAlpha == 255 && mGradientState.mOpaqueOverBounds && isOpaqueForState()) ? 8620a1c6f021be032f5aecb341c2794efb06c0a8a0dAlan Viverette PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT; 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onBoundsChange(Rect r) { 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onBoundsChange(r); 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRingPath = null; 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPathIsDirty = true; 8703aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean onLevelChange(int level) { 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onLevelChange(level); 8763aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPathIsDirty = true; 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidateSelf(); 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8833aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase * This checks mGradientIsDirty, and if it is true, recomputes both our drawing 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rectangle (mRect) and the gradient itself, since it depends on our 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rectangle too. 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the resulting rectangle is not empty, false otherwise 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean ensureValidRect() { 8893aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase if (mGradientIsDirty) { 8903aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = false; 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect bounds = getBounds(); 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float inset = 0; 89417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStrokePaint != null) { 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inset = mStrokePaint.getStrokeWidth() * 0.5f; 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final GradientState st = mGradientState; 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRect.set(bounds.left + inset, bounds.top + inset, 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds.right - inset, bounds.bottom - inset); 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 904e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int[] gradientColors = st.mGradientColors; 905e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (gradientColors != null) { 906e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final RectF r = mRect; 907e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final float x0, x1, y0, y1; 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st.mGradient == LINEAR_GRADIENT) { 9107979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik final float level = st.mUseLevel ? getLevel() / 10000.0f : 1.0f; 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (st.mOrientation) { 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case TOP_BOTTOM: 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.top; 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = x0; y1 = level * r.bottom; 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case TR_BL: 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.right; y0 = r.top; 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.left; y1 = level * r.bottom; 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RIGHT_LEFT: 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.right; y0 = r.top; 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.left; y1 = y0; 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case BR_TL: 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.right; y0 = r.bottom; 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.left; y1 = level * r.top; 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case BOTTOM_TOP: 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.bottom; 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = x0; y1 = level * r.top; 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case BL_TR: 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.bottom; 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.right; y1 = level * r.top; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LEFT_RIGHT: 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.top; 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.right; y1 = y0; 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default:/* TL_BR */ 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.top; 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.right; y1 = level * r.bottom; 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setShader(new LinearGradient(x0, y0, x1, y1, 947e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette gradientColors, st.mPositions, Shader.TileMode.CLAMP)); 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (st.mGradient == RADIAL_GRADIENT) { 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left + (r.right - r.left) * st.mCenterX; 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y0 = r.top + (r.bottom - r.top) * st.mCenterY; 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 952861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette float radius = st.mGradientRadius; 953b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION) { 954b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette // Fall back to parent width or height if intrinsic 955b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette // size is not specified. 956b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette final float width = st.mWidth >= 0 ? st.mWidth : r.width(); 957b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette final float height = st.mHeight >= 0 ? st.mHeight : r.height(); 958b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette radius *= Math.min(width, height); 959b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette } else if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION_PARENT) { 960861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette radius *= Math.min(r.width(), r.height()); 961861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette } 962b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 963861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette if (st.mUseLevel) { 964861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette radius *= getLevel() / 10000.0f; 965861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette } 966b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 967861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette mGradientRadius = radius; 968b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 969b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette if (radius <= 0) { 970b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette // We can't have a shader with non-positive radius, so 971b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette // let's have a very, very small radius. 972b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette radius = 0.001f; 973b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette } 974b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 975861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette mFillPaint.setShader(new RadialGradient( 976e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette x0, y0, radius, gradientColors, null, Shader.TileMode.CLAMP)); 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (st.mGradient == SWEEP_GRADIENT) { 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left + (r.right - r.left) * st.mCenterX; 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y0 = r.top + (r.bottom - r.top) * st.mCenterY; 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 981e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette int[] tempColors = gradientColors; 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] tempPositions = null; 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st.mUseLevel) { 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempColors = st.mTempColors; 986e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int length = gradientColors.length; 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tempColors == null || tempColors.length != length + 1) { 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempColors = st.mTempColors = new int[length + 1]; 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 990e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette System.arraycopy(gradientColors, 0, tempColors, 0, length); 991e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette tempColors[length] = gradientColors[length - 1]; 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempPositions = st.mTempPositions; 99452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float fraction = 1.0f / (length - 1); 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tempPositions == null || tempPositions.length != length + 1) { 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempPositions = st.mTempPositions = new float[length + 1]; 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 99952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float level = getLevel() / 10000.0f; 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < length; i++) { 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempPositions[i] = i * fraction * level; 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempPositions[length] = 1.0f; 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setShader(new SweepGradient(x0, y0, tempColors, tempPositions)); 10074d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette } 10084d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette 10094d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette // If we don't have a solid color, the alpha channel must be 10104d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette // maxed out so that alpha modulation works correctly. 1011e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (st.mSolidColors == null) { 10124d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette mFillPaint.setColor(Color.BLACK); 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return !mRect.isEmpty(); 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 102052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme) 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 102252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawable); 102352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette super.inflateWithAttributes(r, parser, a, R.styleable.GradientDrawable_visible); 102417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateStateFromTypedArray(a); 102552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 102652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 102752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette inflateChildElements(r, parser, attrs, theme); 102852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 102945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(r); 103052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 103152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 103252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 103352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public void applyTheme(Theme t) { 103452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette super.applyTheme(t); 103552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 103652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final GradientState state = mGradientState; 103717cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette if (state == null) { 103817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette return; 103952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 104052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 104117cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette if (state.mThemeAttrs != null) { 104217cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette final TypedArray a = t.resolveAttributes( 104317cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette state.mThemeAttrs, R.styleable.GradientDrawable); 104417cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette updateStateFromTypedArray(a); 104517cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette a.recycle(); 104617cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette } 104752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 104845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (state.mTint != null && state.mTint.canApplyTheme()) { 1049e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette state.mTint = state.mTint.obtainForTheme(t); 105045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 105145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 1052e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mSolidColors != null && state.mSolidColors.canApplyTheme()) { 1053e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette state.mSolidColors = state.mSolidColors.obtainForTheme(t); 105445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 105545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 1056e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mStrokeColors != null && state.mStrokeColors.canApplyTheme()) { 1057e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette state.mStrokeColors = state.mStrokeColors.obtainForTheme(t); 105845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 105945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 106017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette applyThemeChildElements(t); 106152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 106245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(t.getResources()); 106352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 106452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 106552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette /** 106652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * Updates the constant state from the values in the typed array. 106752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette */ 106852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private void updateStateFromTypedArray(TypedArray a) { 106952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final GradientState state = mGradientState; 107052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 10718e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 10728e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= a.getChangingConfigurations(); 10738e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 107417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // Extract the theme attributes, if any. 107517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mThemeAttrs = a.extractThemeAttrs(); 107652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 107717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mShape = a.getInt(R.styleable.GradientDrawable_shape, state.mShape); 107807c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette state.mDither = a.getBoolean(R.styleable.GradientDrawable_dither, state.mDither); 107952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 108052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (state.mShape == RING) { 108117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mInnerRadius = a.getDimensionPixelSize( 108217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_innerRadius, state.mInnerRadius); 108352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 108417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (state.mInnerRadius == -1) { 108552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette state.mInnerRadiusRatio = a.getFloat( 108617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_innerRadiusRatio, state.mInnerRadiusRatio); 108752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 108852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 108917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mThickness = a.getDimensionPixelSize( 109017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_thickness, state.mThickness); 109152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 109217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (state.mThickness == -1) { 109352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette state.mThicknessRatio = a.getFloat( 109417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_thicknessRatio, state.mThicknessRatio); 109552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 109652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 109717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mUseLevelForShape = a.getBoolean( 109817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_useLevel, state.mUseLevelForShape); 109952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 110043027b7bca554818cc4223389747d661819d5706Alan Viverette 110143027b7bca554818cc4223389747d661819d5706Alan Viverette final int tintMode = a.getInt(R.styleable.GradientDrawable_tintMode, -1); 110243027b7bca554818cc4223389747d661819d5706Alan Viverette if (tintMode != -1) { 110343027b7bca554818cc4223389747d661819d5706Alan Viverette state.mTintMode = Drawable.parseTintMode(tintMode, PorterDuff.Mode.SRC_IN); 110443027b7bca554818cc4223389747d661819d5706Alan Viverette } 110543027b7bca554818cc4223389747d661819d5706Alan Viverette 110643027b7bca554818cc4223389747d661819d5706Alan Viverette final ColorStateList tint = a.getColorStateList(R.styleable.GradientDrawable_tint); 110743027b7bca554818cc4223389747d661819d5706Alan Viverette if (tint != null) { 110843027b7bca554818cc4223389747d661819d5706Alan Viverette state.mTint = tint; 110943027b7bca554818cc4223389747d661819d5706Alan Viverette } 111052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 111152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 111252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 111352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public boolean canApplyTheme() { 1114d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette return (mGradientState != null && mGradientState.canApplyTheme()) || super.canApplyTheme(); 111552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 111652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 111752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private void applyThemeChildElements(Theme t) { 111817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 111952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 112017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrSize != null) { 112117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 112217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrSize, R.styleable.GradientDrawableSize); 112317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableSize(a); 112452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 112552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 112652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 112717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrGradient != null) { 112817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 112917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrGradient, R.styleable.GradientDrawableGradient); 113017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette try { 113117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableGradient(t.getResources(), a); 113217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } catch (XmlPullParserException e) { 113317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette throw new RuntimeException(e); 113417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } finally { 113517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a.recycle(); 113617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } 113752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 113852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 113917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrSolid != null) { 114017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 114117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrSolid, R.styleable.GradientDrawableSolid); 114217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableSolid(a); 114352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 114452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 114552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 114617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrStroke != null) { 114717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 114817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrStroke, R.styleable.GradientDrawableStroke); 114917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableStroke(a); 115052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 115152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 115252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 115317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrCorners != null) { 115417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 115517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrCorners, R.styleable.DrawableCorners); 115617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateDrawableCorners(a); 115752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 115852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 115952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 116017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrPadding != null) { 116117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 116217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrPadding, R.styleable.GradientDrawablePadding); 116317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawablePadding(a); 116452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 116552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 116652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 116752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 116852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs, 116952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette Theme theme) throws XmlPullParserException, IOException { 117052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette TypedArray a; 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int type; 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1173ed7894352f8addfe3d0da75cc7fe8bc6fef201dcRomain Guy final int innerDepth = parser.getDepth() + 1; 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int depth; 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((depth=parser.getDepth()) >= innerDepth 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || type != XmlPullParser.END_TAG)) { 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != XmlPullParser.START_TAG) { 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (depth > innerDepth) { 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 118552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = parser.getName(); 118717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name.equals("size")) { 118917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableSize); 119017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableSize(a); 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("gradient")) { 119317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableGradient); 119417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableGradient(r, a); 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("solid")) { 119717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableSolid); 119817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableSolid(a); 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("stroke")) { 120117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableStroke); 120217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableStroke(a); 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("corners")) { 120517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.DrawableCorners); 120617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateDrawableCorners(a); 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("padding")) { 120917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawablePadding); 121017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawablePadding(a); 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("drawable", "Bad element under <shape>: " + name); 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 121552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 121652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 121752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 121817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawablePadding(TypedArray a) { 121917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 122052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 12218e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 12228e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 12238e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 122452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // Extract the theme attributes, if any. 122517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrPadding = a.extractThemeAttrs(); 122617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1227982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette if (st.mPadding == null) { 1228982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette st.mPadding = new Rect(); 1229982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette } 1230982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette 123117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final Rect pad = st.mPadding; 123217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette pad.set(a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_left, pad.left), 123317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_top, pad.top), 123417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_right, pad.right), 123517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_bottom, pad.bottom)); 123617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette mPadding = pad; 123752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 1238e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 123917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateDrawableCorners(TypedArray a) { 124017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 124117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 12428e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 12438e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 12448e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 124517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // Extract the theme attributes, if any. 124617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrCorners = a.extractThemeAttrs(); 124717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 124817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int radius = a.getDimensionPixelSize( 124917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.DrawableCorners_radius, (int) st.mRadius); 125052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setCornerRadius(radius); 125117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 125217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // TODO: Update these to be themeable. 125317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int topLeftRadius = a.getDimensionPixelSize( 125452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.DrawableCorners_topLeftRadius, radius); 125517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int topRightRadius = a.getDimensionPixelSize( 125652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.DrawableCorners_topRightRadius, radius); 125717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int bottomLeftRadius = a.getDimensionPixelSize( 125852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.DrawableCorners_bottomLeftRadius, radius); 125917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int bottomRightRadius = a.getDimensionPixelSize( 126052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.DrawableCorners_bottomRightRadius, radius); 126152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (topLeftRadius != radius || topRightRadius != radius || 126252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette bottomLeftRadius != radius || bottomRightRadius != radius) { 126352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // The corner radii are specified in clockwise order (see Path.addRoundRect()) 126452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setCornerRadii(new float[] { 126552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette topLeftRadius, topLeftRadius, 126652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette topRightRadius, topRightRadius, 126752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette bottomRightRadius, bottomRightRadius, 126852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette bottomLeftRadius, bottomLeftRadius 126952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette }); 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 127152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 127252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 127317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawableStroke(TypedArray a) { 127417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 127517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 12768e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 12778e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 12788e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 12798e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Extract the theme attributes, if any. 128017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrStroke = a.extractThemeAttrs(); 128117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 12823b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette // We have an explicit stroke defined, so the default stroke width 12833b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette // must be at least 0 or the current stroke width. 12843b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final int defaultStrokeWidth = Math.max(0, st.mStrokeWidth); 128552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int width = a.getDimensionPixelSize( 12863b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette R.styleable.GradientDrawableStroke_width, defaultStrokeWidth); 128752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float dashWidth = a.getDimension( 128817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableStroke_dashWidth, st.mStrokeDashWidth); 128917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 129017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette ColorStateList colorStateList = a.getColorStateList( 129117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableStroke_color); 129217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (colorStateList == null) { 1293e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette colorStateList = st.mStrokeColors; 129417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } 129517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 129652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (dashWidth != 0.0f) { 129752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float dashGap = a.getDimension( 129817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableStroke_dashGap, st.mStrokeDashGap); 129952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setStroke(width, colorStateList, dashWidth, dashGap); 130052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 130152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setStroke(width, colorStateList); 130252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 130352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 130452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 130517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawableSolid(TypedArray a) { 13068e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final GradientState st = mGradientState; 13078e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 13088e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 13098e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 13108e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 13118e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Extract the theme attributes, if any. 13128e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mAttrSolid = a.extractThemeAttrs(); 131317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 131452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final ColorStateList colorStateList = a.getColorStateList( 131552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableSolid_color); 131617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (colorStateList != null) { 131717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette setColor(colorStateList); 131817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } 131952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 132052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 132117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawableGradient(Resources r, TypedArray a) 132252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette throws XmlPullParserException { 132352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final GradientState st = mGradientState; 132417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 13258e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 13268e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 13278e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 132817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // Extract the theme attributes, if any. 132917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrGradient = a.extractThemeAttrs(); 133017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 133117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mCenterX = getFloatOrFraction( 133217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a, R.styleable.GradientDrawableGradient_centerX, st.mCenterX); 133317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mCenterY = getFloatOrFraction( 133417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a, R.styleable.GradientDrawableGradient_centerY, st.mCenterY); 133517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mUseLevel = a.getBoolean( 133617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableGradient_useLevel, st.mUseLevel); 133717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mGradient = a.getInt( 133817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableGradient_type, st.mGradient); 133917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 134017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // TODO: Update these to be themeable. 134152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int startColor = a.getColor( 134252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableGradient_startColor, 0); 134352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final boolean hasCenterColor = a.hasValue( 134452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableGradient_centerColor); 134552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int centerColor = a.getColor( 134652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableGradient_centerColor, 0); 134752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int endColor = a.getColor( 134852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableGradient_endColor, 0); 134952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 135052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (hasCenterColor) { 1351e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors = new int[3]; 1352e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[0] = startColor; 1353e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[1] = centerColor; 1354e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[2] = endColor; 135517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 135652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mPositions = new float[3]; 135752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mPositions[0] = 0.0f; 135852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // Since 0.5f is default value, try to take the one that isn't 0.5f 135952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mPositions[1] = st.mCenterX != 0.5f ? st.mCenterX : st.mCenterY; 136052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mPositions[2] = 1f; 136152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 1362e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors = new int[2]; 1363e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[0] = startColor; 1364e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[1] = endColor; 136552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 136652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 136752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (st.mGradient == LINEAR_GRADIENT) { 136817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle); 136952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette angle %= 360; 137052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 137152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (angle % 45 != 0) { 137252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette throw new XmlPullParserException(a.getPositionDescription() 137352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette + "<gradient> tag requires 'angle' attribute to " 137452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette + "be a multiple of 45"); 137552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 137652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 137717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAngle = angle; 137817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 137952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette switch (angle) { 138052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 0: 138152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.LEFT_RIGHT; 138252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 138352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 45: 138452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.BL_TR; 138552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 138652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 90: 138752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.BOTTOM_TOP; 138852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 138952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 135: 139052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.BR_TL; 139152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 139252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 180: 139352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.RIGHT_LEFT; 139452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 139552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 225: 139652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.TR_BL; 139752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 139852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 270: 139952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.TOP_BOTTOM; 140052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 140152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 315: 140252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.TL_BR; 140352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 140452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 140552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 140617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius); 140752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (tv != null) { 140852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float radius; 140952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int radiusType; 141052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (tv.type == TypedValue.TYPE_FRACTION) { 141152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radius = tv.getFraction(1.0f, 1.0f); 141252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 141352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT) 141452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette & TypedValue.COMPLEX_UNIT_MASK; 141552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) { 141652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radiusType = RADIUS_TYPE_FRACTION_PARENT; 141752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 141852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radiusType = RADIUS_TYPE_FRACTION; 141952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 14202efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette } else if (tv.type == TypedValue.TYPE_DIMENSION) { 142152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radius = tv.getDimension(r.getDisplayMetrics()); 142252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radiusType = RADIUS_TYPE_PIXELS; 14232efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette } else { 14242efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette radius = tv.getFloat(); 14252efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette radiusType = RADIUS_TYPE_PIXELS; 142652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 142752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 142852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mGradientRadius = radius; 142952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mGradientRadiusType = radiusType; 143052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else if (st.mGradient == RADIAL_GRADIENT) { 143152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette throw new XmlPullParserException( 143252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.getPositionDescription() 143352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette + "<gradient> tag requires 'gradientRadius' " 143452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette + "attribute with radial type"); 143552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 143652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 143752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 143852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 143917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawableSize(TypedArray a) { 144017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 144152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 14428e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 14438e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 14448e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 144552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // Extract the theme attributes, if any. 144617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrSize = a.extractThemeAttrs(); 144717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 144817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mWidth = a.getDimensionPixelSize(R.styleable.GradientDrawableSize_width, st.mWidth); 144917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mHeight = a.getDimensionPixelSize(R.styleable.GradientDrawableSize_height, st.mHeight); 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static float getFloatOrFraction(TypedArray a, int index, float defaultValue) { 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedValue tv = a.peekValue(index); 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v = defaultValue; 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tv != null) { 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean vIsFraction = tv.type == TypedValue.TYPE_FRACTION; 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v = vIsFraction ? tv.getFraction(1.0f, 1.0f) : tv.getFloat(); 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return v; 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 146117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicWidth() { 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mGradientState.mWidth; 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicHeight() { 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mGradientState.mHeight; 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 147117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ConstantState getConstantState() { 14746efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais mGradientState.mChangingConfigurations = getChangingConfigurations(); 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mGradientState; 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1478888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette private boolean isOpaqueForState() { 1479888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette if (mGradientState.mStrokeWidth >= 0 && mStrokePaint != null 1480888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette && !isOpaque(mStrokePaint.getColor())) { 1481888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return false; 1482888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette } 1483888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette 1484888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette if (!isOpaque(mFillPaint.getColor())) { 1485888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return false; 1486888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette } 1487888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette 1488888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return true; 1489888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette } 1490888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 149231ba192dd201df2cad96a8c503f730130ab0d80fChris Craik public void getOutline(Outline outline) { 1493b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik final GradientState st = mGradientState; 1494b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik final Rect bounds = getBounds(); 1495c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik // only report non-zero alpha if shape being drawn is opaque 1496888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette outline.setAlpha(st.mOpaqueOverShape && isOpaqueForState() ? (mAlpha / 255.0f) : 0.0f); 1497b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik 1498b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik switch (st.mShape) { 1499b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik case RECTANGLE: 1500b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik if (st.mRadiusArray != null) { 1501e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik buildPathIfDirty(); 1502e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik outline.setConvexPath(mPath); 150331ba192dd201df2cad96a8c503f730130ab0d80fChris Craik return; 1504b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik } 1505e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 1506b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik float rad = 0; 1507b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik if (st.mRadius > 0.0f) { 1508b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik // clamp the radius based on width & height, matching behavior in draw() 1509b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik rad = Math.min(st.mRadius, 1510b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik Math.min(bounds.width(), bounds.height()) * 0.5f); 1511b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik } 15127979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik outline.setRoundRect(bounds, rad); 151331ba192dd201df2cad96a8c503f730130ab0d80fChris Craik return; 15147979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik case OVAL: 15157979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik outline.setOval(bounds); 151631ba192dd201df2cad96a8c503f730130ab0d80fChris Craik return; 15177979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik case LINE: 15183b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette // Hairlines (0-width stroke) must have a non-empty outline for 15193b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette // shadows to draw correctly, so we'll use a very small width. 15203b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final float halfStrokeWidth = mStrokePaint == null ? 15213b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette 0.0001f : mStrokePaint.getStrokeWidth() * 0.5f; 15223b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final float centerY = bounds.centerY(); 15233b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final int top = (int) Math.floor(centerY - halfStrokeWidth); 15243b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final int bottom = (int) Math.ceil(centerY + halfStrokeWidth); 1525b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik 1526e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik outline.setRect(bounds.left, top, bounds.right, bottom); 152731ba192dd201df2cad96a8c503f730130ab0d80fChris Craik return; 1528b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik default: 152931ba192dd201df2cad96a8c503f730130ab0d80fChris Craik // TODO: support more complex shapes 1530b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik } 1531b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik } 1532b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik 1533b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik @Override 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable mutate() { 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mMutated && super.mutate() == this) { 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState = new GradientState(mGradientState); 153745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(null); 15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutated = true; 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1543727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette /** 1544727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette * @hide 1545727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette */ 1546727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette public void clearMutated() { 1547727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette super.clearMutated(); 1548727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mMutated = false; 1549727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 1550727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final static class GradientState extends ConstantState { 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mChangingConfigurations; 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mShape = RECTANGLE; 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mGradient = LINEAR_GRADIENT; 155571b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public int mAngle = 0; 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Orientation mOrientation; 1557e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public ColorStateList mSolidColors; 1558e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public ColorStateList mStrokeColors; 1559e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public int[] mGradientColors; 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int[] mTempColors; // no need to copy 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float[] mTempPositions; // no need to copy 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float[] mPositions; 156371b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public int mStrokeWidth = -1; // if >= 0 use stroking. 156471b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public float mStrokeDashWidth = 0.0f; 156571b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public float mStrokeDashGap = 0.0f; 156671b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public float mRadius = 0.0f; // use this if mRadiusArray is null 156771b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public float[] mRadiusArray = null; 156871b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public Rect mPadding = null; 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mWidth = -1; 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mHeight = -1; 157117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public float mInnerRadiusRatio = DEFAULT_INNER_RADIUS_RATIO; 157217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public float mThicknessRatio = DEFAULT_THICKNESS_RATIO; 157317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public int mInnerRadius = -1; 157417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public int mThickness = -1; 157507c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette public boolean mDither = false; 157607c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette 1577969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette float mCenterX = 0.5f; 1578969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette float mCenterY = 0.5f; 1579969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette float mGradientRadius = 0.5f; 1580969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette int mGradientRadiusType = RADIUS_TYPE_PIXELS; 1581969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette boolean mUseLevel = false; 1582969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette boolean mUseLevelForShape = true; 1583969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette 1584969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette boolean mOpaqueOverBounds; 1585969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette boolean mOpaqueOverShape; 15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 158743027b7bca554818cc4223389747d661819d5706Alan Viverette ColorStateList mTint = null; 158843027b7bca554818cc4223389747d661819d5706Alan Viverette PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE; 158943027b7bca554818cc4223389747d661819d5706Alan Viverette 159052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mThemeAttrs; 159152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrSize; 159252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrGradient; 159352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrSolid; 159452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrStroke; 159552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrCorners; 159652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrPadding; 159752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 1598e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public GradientState(Orientation orientation, int[] gradientColors) { 15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOrientation = orientation; 1600e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette setGradientColors(gradientColors); 16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GradientState(GradientState state) { 16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChangingConfigurations = state.mChangingConfigurations; 16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShape = state.mShape; 16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradient = state.mGradient; 160717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette mAngle = state.mAngle; 16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOrientation = state.mOrientation; 1609e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mSolidColors = state.mSolidColors; 1610e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mGradientColors != null) { 1611e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientColors = state.mGradientColors.clone(); 1612562bf17c6c7c5226b2220e27a1543d4a43543d6cPhil Dubach } 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (state.mPositions != null) { 16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPositions = state.mPositions.clone(); 16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1616e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mStrokeColors = state.mStrokeColors; 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokeWidth = state.mStrokeWidth; 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokeDashWidth = state.mStrokeDashWidth; 16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokeDashGap = state.mStrokeDashGap; 16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadius = state.mRadius; 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (state.mRadiusArray != null) { 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadiusArray = state.mRadiusArray.clone(); 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (state.mPadding != null) { 1625982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette mPadding = new Rect(state.mPadding); 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = state.mWidth; 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = state.mHeight; 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInnerRadiusRatio = state.mInnerRadiusRatio; 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThicknessRatio = state.mThicknessRatio; 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInnerRadius = state.mInnerRadius; 16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThickness = state.mThickness; 163307c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mDither = state.mDither; 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCenterX = state.mCenterX; 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCenterY = state.mCenterY; 16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientRadius = state.mGradientRadius; 1637b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette mGradientRadiusType = state.mGradientRadiusType; 16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUseLevel = state.mUseLevel; 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUseLevelForShape = state.mUseLevelForShape; 1640c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverBounds = state.mOpaqueOverBounds; 1641c3a63c1fbb47f167f6736ad637fd6c6e3ee9d1d8Alan Viverette mOpaqueOverShape = state.mOpaqueOverShape; 164243027b7bca554818cc4223389747d661819d5706Alan Viverette mTint = state.mTint; 164343027b7bca554818cc4223389747d661819d5706Alan Viverette mTintMode = state.mTintMode; 164452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mThemeAttrs = state.mThemeAttrs; 164552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mAttrSize = state.mAttrSize; 164652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mAttrGradient = state.mAttrGradient; 164752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mAttrSolid = state.mAttrSolid; 164852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mAttrStroke = state.mAttrStroke; 164952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mAttrCorners = state.mAttrCorners; 165052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette mAttrPadding = state.mAttrPadding; 165152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 165252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 165352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 165452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public boolean canApplyTheme() { 165545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return mThemeAttrs != null 165645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || mAttrSize != null || mAttrGradient != null 165745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || mAttrSolid != null || mAttrStroke != null 165845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || mAttrCorners != null || mAttrPadding != null 165945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || (mTint != null && mTint.canApplyTheme()) 1660e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette || (mStrokeColors != null && mStrokeColors.canApplyTheme()) 1661e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette || (mSolidColors != null && mSolidColors.canApplyTheme()) 166245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || super.canApplyTheme(); 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable newDrawable() { 166745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return new GradientDrawable(this, null); 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 166917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1671c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn public Drawable newDrawable(Resources res) { 167245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return new GradientDrawable(this, res); 1673c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 167417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1675c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn @Override 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChangingConfigurations() { 1677e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return mChangingConfigurations 1678e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette | (mStrokeColors != null ? mStrokeColors.getChangingConfigurations() : 0) 1679e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette | (mSolidColors != null ? mSolidColors.getChangingConfigurations() : 0) 1680e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette | (mTint != null ? mTint.getChangingConfigurations() : 0); 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setShape(int shape) { 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShape = shape; 1685e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy computeOpacity(); 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGradientType(int gradient) { 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradient = gradient; 16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGradientCenter(float x, float y) { 16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCenterX = x; 16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCenterY = y; 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1697e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public void setGradientColors(int[] colors) { 1698e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientColors = colors; 1699e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mSolidColors = null; 1700e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy computeOpacity(); 17018bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy } 1702519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 1703e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public void setSolidColors(ColorStateList colors) { 1704e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientColors = null; 1705e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mSolidColors = colors; 1706e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy computeOpacity(); 1707e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 1708e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 1709e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy private void computeOpacity() { 1710c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverBounds = false; 1711c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverShape = false; 171239824f685c33f8aabbe9526b4cc79b7411e8b37fRaph Levien 1713e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (mGradientColors != null) { 1714e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette for (int i = 0; i < mGradientColors.length; i++) { 1715e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (!isOpaque(mGradientColors[i])) { 1716e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy return; 1717e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 1718e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 1719e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 1720e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 172122cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase // An unfilled shape is not opaque over bounds or shape 1722e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (mGradientColors == null && mSolidColors == null) { 172322cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase return; 172422cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase } 172522cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase 1726c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik // Colors are opaque, so opaqueOverShape=true, 1727c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverShape = true; 1728c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik // and opaqueOverBounds=true if shape fills bounds 1729c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverBounds = mShape == RECTANGLE 1730c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik && mRadius <= 0 1731c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik && mRadiusArray == null; 1732e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 1733e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 1734e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public void setStroke(int width, ColorStateList colors, float dashWidth, float dashGap) { 1735a211dd28b93473c452d68432c602d5209b01c178Alan Viverette mStrokeWidth = width; 1736e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mStrokeColors = colors; 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokeDashWidth = dashWidth; 17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokeDashGap = dashGap; 1739e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy computeOpacity(); 17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setCornerRadius(float radius) { 17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (radius < 0) { 17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radius = 0; 17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadius = radius; 17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadiusArray = null; 17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1749e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setCornerRadii(float[] radii) { 17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadiusArray = radii; 17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (radii == null) { 17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadius = 0; 17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1756e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setSize(int width, int height) { 17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = width; 17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = height; 17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1762861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette public void setGradientRadius(float gradientRadius, int type) { 17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientRadius = gradientRadius; 1764b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette mGradientRadiusType = type; 17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1768888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette static boolean isOpaque(int color) { 1769888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return ((color >> 24) & 0xff) == 0xff; 1770888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette } 1771888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette 177252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette /** 177352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * Creates a new themed GradientDrawable based on the specified constant state. 177452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * <p> 177552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * The resulting drawable is guaranteed to have a new constant state. 177652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * 177752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * @param state Constant state from which the drawable inherits 177852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette */ 177945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private GradientDrawable(GradientState state, Resources res) { 178017cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette mGradientState = state; 178152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 178245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(res); 17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 178545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private void updateLocalState(Resources res) { 178645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final GradientState state = mGradientState; 178745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 1788e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mSolidColors != null) { 1789519494e207322581075c8ea884fde9d33bb9209eAlan Viverette final int[] currentState = getState(); 1790e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int stateColor = state.mSolidColors.getColorForState(currentState, 0); 1791519494e207322581075c8ea884fde9d33bb9209eAlan Viverette mFillPaint.setColor(stateColor); 1792e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette } else if (state.mGradientColors == null) { 1793cf8675ee176a375f873792684d38a47f78348dffRomain Guy // If we don't have a solid color and we don't have a gradient, 1794cf8675ee176a375f873792684d38a47f78348dffRomain Guy // the app is stroking the shape, set the color to the default 1795cf8675ee176a375f873792684d38a47f78348dffRomain Guy // value of state.mSolidColor 1796cf8675ee176a375f873792684d38a47f78348dffRomain Guy mFillPaint.setColor(0); 17974d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette } else { 17984d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette // Otherwise, make sure the fill alpha is maxed out. 17994d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette mFillPaint.setColor(Color.BLACK); 18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 180117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPadding = state.mPadding; 180317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (state.mStrokeWidth >= 0) { 18056a49ddef62865c1b245ad60a13c334f0ffaf1a5fChris Craik mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setStyle(Paint.Style.STROKE); 18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setStrokeWidth(state.mStrokeWidth); 180817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1809e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mStrokeColors != null) { 1810083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette final int[] currentState = getState(); 1811e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int strokeStateColor = state.mStrokeColors.getColorForState( 1812083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette currentState, 0); 1813083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette mStrokePaint.setColor(strokeStateColor); 1814083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette } 18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (state.mStrokeDashWidth != 0.0f) { 181717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final DashPathEffect e = new DashPathEffect( 18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new float[] { state.mStrokeDashWidth, state.mStrokeDashGap }, 0); 18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setPathEffect(e); 18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18223ad771b384b55bc0b9ee9519f457ea7093bb0b74Alan Viverette 1823daec594370f0e47bf07d0c9c968e3c5dfedf0bb5Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 182445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mGradientIsDirty = true; 182545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 182645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette state.computeOpacity(); 18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1829