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; 205f63721a6c2c29e639d8d239834a825c535c034aAlan Viveretteimport android.annotation.IntDef; 21ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viveretteimport android.annotation.NonNull; 2241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viveretteimport android.annotation.Nullable; 23ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viveretteimport android.content.pm.ActivityInfo.Config; 24519494e207322581075c8ea884fde9d33bb9209eAlan Viveretteimport android.content.res.ColorStateList; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 2652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport android.content.res.Resources.Theme; 2741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viveretteimport android.content.res.TypedArray; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas; 294d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viveretteimport android.graphics.Color; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.ColorFilter; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.DashPathEffect; 3287e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viveretteimport android.graphics.Insets; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.LinearGradient; 34b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craikimport android.graphics.Outline; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Paint; 36519494e207322581075c8ea884fde9d33bb9209eAlan Viveretteimport android.graphics.Path; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 3843027b7bca554818cc4223389747d661819d5706Alan Viveretteimport android.graphics.PorterDuff; 3943027b7bca554818cc4223389747d661819d5706Alan Viveretteimport android.graphics.PorterDuffColorFilter; 40519494e207322581075c8ea884fde9d33bb9209eAlan Viveretteimport android.graphics.RadialGradient; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.RectF; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Shader; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.SweepGradient; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 46ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viveretteimport android.util.DisplayMetrics; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.TypedValue; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viveretteimport com.android.internal.R; 5152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 565f63721a6c2c29e639d8d239834a825c535c034aAlan Viveretteimport java.lang.annotation.Retention; 575f63721a6c2c29e639d8d239834a825c535c034aAlan Viveretteimport java.lang.annotation.RetentionPolicy; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 6017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * A Drawable with a color gradient for buttons, backgrounds, etc. 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 62dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * <p>It can be defined in an XML file with the <code><shape></code> element. For more 63dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * information, see the guide to <a 64dfe5c204403bc56c29bb36410574eab8b1950417Scott Main * href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.</p> 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_visible 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_shape 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_innerRadiusRatio 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_innerRadius 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_thicknessRatio 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_thickness 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawable_useLevel 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableSize_width 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableSize_height 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_startColor 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_centerColor 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_endColor 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_useLevel 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_angle 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_type 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_centerX 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_centerY 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableGradient_gradientRadius 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableSolid_color 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableStroke_width 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableStroke_color 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableStroke_dashWidth 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawableStroke_dashGap 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawablePadding_left 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawablePadding_top 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawablePadding_right 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GradientDrawablePadding_bottom 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class GradientDrawable extends Drawable { 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shape is a rectangle, possibly with rounded corners 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RECTANGLE = 0; 9917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shape is an ellipse 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public static final int OVAL = 1; 10417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shape is a line 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int LINE = 2; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shape is a ring. 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RING = 3; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1155f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette /** @hide */ 1165f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @IntDef({RECTANGLE, OVAL, LINE, RING}) 1175f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @Retention(RetentionPolicy.SOURCE) 1185f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public @interface Shape {} 1195f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gradient is linear (default.) 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int LINEAR_GRADIENT = 0; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gradient is circular. 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RADIAL_GRADIENT = 1; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gradient is a sweep. 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SWEEP_GRADIENT = 2; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1355f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette /** @hide */ 1365f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @IntDef({LINEAR_GRADIENT, RADIAL_GRADIENT, SWEEP_GRADIENT}) 1375f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @Retention(RetentionPolicy.SOURCE) 1385f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public @interface GradientType {} 1395f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette 140b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette /** Radius is in pixels. */ 141b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette private static final int RADIUS_TYPE_PIXELS = 0; 142b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 143b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette /** Radius is a fraction of the base size. */ 144b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette private static final int RADIUS_TYPE_FRACTION = 1; 145b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 146b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette /** Radius is a fraction of the bounds size. */ 147b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette private static final int RADIUS_TYPE_FRACTION_PARENT = 2; 148b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 1495f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette /** @hide */ 1505f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @IntDef({RADIUS_TYPE_PIXELS, RADIUS_TYPE_FRACTION, RADIUS_TYPE_FRACTION_PARENT}) 1515f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @Retention(RetentionPolicy.SOURCE) 1525f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public @interface RadiusType {} 1535f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette 15452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private static final float DEFAULT_INNER_RADIUS_RATIO = 3.0f; 15552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private static final float DEFAULT_THICKNESS_RATIO = 9.0f; 15652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GradientState mGradientState; 15817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1596a49ddef62865c1b245ad60a13c334f0ffaf1a5fChris Craik private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Rect mPadding; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Paint mStrokePaint; // optional, set by the caller 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ColorFilter mColorFilter; // optional, set by the caller 16343027b7bca554818cc4223389747d661819d5706Alan Viverette private PorterDuffColorFilter mTintFilter; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mAlpha = 0xFF; // modified by the caller 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Path mPath = new Path(); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final RectF mRect = new RectF(); 168e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Paint mLayerPaint; // internal, used if we use saveLayer() 17045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private boolean mGradientIsDirty; 171684385ddde2ac0c26de0862390ad713aff3fb149Romain Guy private boolean mMutated; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Path mRingPath; 1731041aded2df45094c36831028245fb7c5e9b67b7Romain Guy private boolean mPathIsDirty = true; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1753aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase /** Current gradient radius, valid when {@link #mGradientIsDirty} is false. */ 176861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette private float mGradientRadius; 177861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Controls how the gradient is oriented relative to the drawable's bounds 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public enum Orientation { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the top to the bottom */ 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TOP_BOTTOM, 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the top-right to the bottom-left */ 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TR_BL, 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the right to the left */ 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RIGHT_LEFT, 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the bottom-right to the top-left */ 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BR_TL, 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the bottom to the top */ 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BOTTOM_TOP, 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the bottom-left to the top-right */ 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BL_TR, 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the left to the right */ 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LEFT_RIGHT, 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** draw the gradient from the top-left to the bottom-right */ 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TL_BR, 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GradientDrawable() { 20145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette this(new GradientState(Orientation.TOP_BOTTOM, null), null); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new gradient drawable given an orientation and an array 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of colors for the gradient. 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20880756e38882720860db52f1fcc21fa1505a02abfTor Norbye public GradientDrawable(Orientation orientation, @ColorInt int[] colors) { 20945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette this(new GradientState(orientation, colors), null); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean getPadding(Rect padding) { 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPadding != null) { 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project padding.set(mPadding); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.getPadding(padding); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 22341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Specifies radii for each of the 4 corners. For each corner, the array 22441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * contains 2 values, <code>[X_radius, Y_radius]</code>. The corners are 22541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * ordered top-left, top-right, bottom-right, bottom-left. This property 22641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * is honored only when the shape is of type {@link #RECTANGLE}. 22741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 22841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <strong>Note</strong>: changing this property will affect all instances 2298bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 23041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing this property. 2318bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 23241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @param radii an array of length >= 8 containing 4 pairs of X and Y 23341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * radius for each corner, specified in pixels 2348bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 2358bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 2368bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #setShape(int) 23741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setCornerRadius(float) 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 23941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette public void setCornerRadii(@Nullable float[] radii) { 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.setCornerRadii(radii); 2411041aded2df45094c36831028245fb7c5e9b67b7Romain Guy mPathIsDirty = true; 2429891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 24641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Returns the radii for each of the 4 corners. For each corner, the array 24741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * contains 2 values, <code>[X_radius, Y_radius]</code>. The corners are 24841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * ordered top-left, top-right, bottom-right, bottom-left. 24941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 25041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * If the radius was previously set with {@link #setCornerRadius(float)}, 25141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * or if the corners are not rounded, this method will return {@code null}. 25241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 25341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return an array containing the radii for each of the 4 corners, or 25441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@code null} 25541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setCornerRadii(float[]) 25641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 25741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette @Nullable 25841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette public float[] getCornerRadii() { 25941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette return mGradientState.mRadiusArray.clone(); 26041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 26141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 26241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 26341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Specifies the radius for the corners of the gradient. If this is > 0, 26441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * then the drawable is drawn in a round-rectangle, rather than a 26541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * rectangle. This property is honored only when the shape is of type 26641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #RECTANGLE}. 26741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 26841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <strong>Note</strong>: changing this property will affect all instances 2698bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 27041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing this property. 2718bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 2728bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param radius The radius in pixels of the corners of the rectangle shape 2738bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 2748bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 2758bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #setCornerRadii(float[]) 27617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setShape(int) 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setCornerRadius(float radius) { 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.setCornerRadius(radius); 2801041aded2df45094c36831028245fb7c5e9b67b7Romain Guy mPathIsDirty = true; 2819891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2838bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 28541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Returns the radius for the corners of the gradient. 28641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 28741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * If the radius was previously set with {@link #setCornerRadii(float[])}, 28841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * or if the corners are not rounded, this method will return {@code null}. 28941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 29041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return the radius in pixels of the corners of the rectangle shape, or 0 29141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setCornerRadius 29241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 29341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette public float getCornerRadius() { 29441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette return mGradientState.mRadius; 29541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 29641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 29741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 2988bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Set the stroke width and color for the drawable. If width is zero, 2998bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * then no stroke is drawn.</p> 3008bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 3018bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 3028bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 3038bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 3048bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param width The width in pixels of the stroke 3058bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param color The color of the stroke 3068bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 3078bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 30817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setStroke(int, int, float, float) 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 31080756e38882720860db52f1fcc21fa1505a02abfTor Norbye public void setStroke(int width, @ColorInt int color) { 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setStroke(width, color, 0, 0); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3138bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 3148bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 315a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * <p>Set the stroke width and color state list for the drawable. If width 316a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * is zero, then no stroke is drawn.</p> 317a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * <p><strong>Note</strong>: changing this property will affect all instances 318a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * of a drawable loaded from a resource. It is recommended to invoke 319a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * {@link #mutate()} before changing this property.</p> 320a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * 321a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @param width The width in pixels of the stroke 322a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @param colorStateList The color state list of the stroke 323a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * 324a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @see #mutate() 325a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @see #setStroke(int, ColorStateList, float, float) 326a211dd28b93473c452d68432c602d5209b01c178Alan Viverette */ 327a211dd28b93473c452d68432c602d5209b01c178Alan Viverette public void setStroke(int width, ColorStateList colorStateList) { 328a211dd28b93473c452d68432c602d5209b01c178Alan Viverette setStroke(width, colorStateList, 0, 0); 329a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 330a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 331a211dd28b93473c452d68432c602d5209b01c178Alan Viverette /** 3328bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Set the stroke width and color for the drawable. If width is zero, 3338bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * then no stroke is drawn. This method can also be used to dash the stroke.</p> 3348bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 3358bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 3368bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 3378bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 3388bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param width The width in pixels of the stroke 3398bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param color The color of the stroke 34017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes 3418bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param dashGap The gap in pixels between dashes 3428bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 3438bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 34417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setStroke(int, int) 3458bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 34680756e38882720860db52f1fcc21fa1505a02abfTor Norbye public void setStroke(int width, @ColorInt int color, float dashWidth, float dashGap) { 34740df78153987409dbf299b84da9784b69029e184Alan Viverette mGradientState.setStroke(width, ColorStateList.valueOf(color), dashWidth, dashGap); 348a211dd28b93473c452d68432c602d5209b01c178Alan Viverette setStrokeInternal(width, color, dashWidth, dashGap); 349a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 351a211dd28b93473c452d68432c602d5209b01c178Alan Viverette /** 352a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * <p>Set the stroke width and color state list for the drawable. If width 353a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * is zero, then no stroke is drawn. This method can also be used to dash 354a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * the stroke.</p> 355a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * <p><strong>Note</strong>: changing this property will affect all instances 356a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * of a drawable loaded from a resource. It is recommended to invoke 357a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * {@link #mutate()} before changing this property.</p> 358a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * 359a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @param width The width in pixels of the stroke 360a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @param colorStateList The color state list of the stroke 361a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes 362a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @param dashGap The gap in pixels between dashes 363a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * 364a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @see #mutate() 365a211dd28b93473c452d68432c602d5209b01c178Alan Viverette * @see #setStroke(int, ColorStateList) 366a211dd28b93473c452d68432c602d5209b01c178Alan Viverette */ 367a211dd28b93473c452d68432c602d5209b01c178Alan Viverette public void setStroke( 368a211dd28b93473c452d68432c602d5209b01c178Alan Viverette int width, ColorStateList colorStateList, float dashWidth, float dashGap) { 36940df78153987409dbf299b84da9784b69029e184Alan Viverette mGradientState.setStroke(width, colorStateList, dashWidth, dashGap); 37040df78153987409dbf299b84da9784b69029e184Alan Viverette final int color; 3717c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette if (colorStateList == null) { 37240df78153987409dbf299b84da9784b69029e184Alan Viverette color = Color.TRANSPARENT; 3737c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette } else { 3747c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette final int[] stateSet = getState(); 37540df78153987409dbf299b84da9784b69029e184Alan Viverette color = colorStateList.getColorForState(stateSet, 0); 3767c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette } 37740df78153987409dbf299b84da9784b69029e184Alan Viverette setStrokeInternal(width, color, dashWidth, dashGap); 378a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 379a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 380a211dd28b93473c452d68432c602d5209b01c178Alan Viverette private void setStrokeInternal(int width, int color, float dashWidth, float dashGap) { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStrokePaint == null) { 3826a49ddef62865c1b245ad60a13c334f0ffaf1a5fChris Craik mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setStyle(Paint.Style.STROKE); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setStrokeWidth(width); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setColor(color); 38717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DashPathEffect e = null; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dashWidth > 0) { 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e = new DashPathEffect(new float[] { dashWidth, dashGap }, 0); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setPathEffect(e); 3939891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3958bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 3968bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 3978bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 3988bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Sets the size of the shape drawn by this drawable.</p> 3998bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 4008bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 4018bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 4028bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4038bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param width The width of the shape used by this drawable 4048bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param height The height of the shape used by this drawable 4058bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4068bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 4078bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #setGradientType(int) 4088bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setSize(int width, int height) { 4101041aded2df45094c36831028245fb7c5e9b67b7Romain Guy mGradientState.setSize(width, height); 4111041aded2df45094c36831028245fb7c5e9b67b7Romain Guy mPathIsDirty = true; 4129891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4148bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 4158bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 4168bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p>Sets the type of shape used to draw the gradient.</p> 4178bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * <p><strong>Note</strong>: changing this property will affect all instances 4188bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 4198bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #mutate()} before changing this property.</p> 4208bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4218bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param shape The desired shape for this drawable: {@link #LINE}, 4228bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #OVAL}, {@link #RECTANGLE} or {@link #RING} 4238bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4248bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 4258bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 4265f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setShape(@Shape int shape) { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRingPath = null; 4281041aded2df45094c36831028245fb7c5e9b67b7Romain Guy mPathIsDirty = true; 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.setShape(shape); 4309891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4338bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 4345f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette * Returns the type of shape used by this drawable, one of {@link #LINE}, 4355f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette * {@link #OVAL}, {@link #RECTANGLE} or {@link #RING}. 4365f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette * 4375f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette * @return the type of shape used by this drawable 4385f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette * @see #setShape(int) 4395f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette */ 4405f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @Shape 4415f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public int getShape() { 4425f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette return mGradientState.mShape; 4435f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette } 4445f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette 4455f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette /** 44641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Sets the type of gradient used by this drawable. 44741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 44841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <strong>Note</strong>: changing this property will affect all instances 4498bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 45041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing this property. 4518bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4528bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param gradient The type of the gradient: {@link #LINEAR_GRADIENT}, 4538bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * {@link #RADIAL_GRADIENT} or {@link #SWEEP_GRADIENT} 4548bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4558bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 45641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getGradientType() 4578bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 4585f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setGradientType(@GradientType int gradient) { 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.setGradientType(gradient); 4603aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 4619891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4648bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 46541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Returns the type of gradient used by this drawable, one of 46641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #LINEAR_GRADIENT}, {@link #RADIAL_GRADIENT}, or 46741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #SWEEP_GRADIENT}. 46841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 46941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return the type of gradient used by this drawable 47041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setGradientType(int) 47141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 4725f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @GradientType 47341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette public int getGradientType() { 47441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette return mGradientState.mGradient; 47541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 47641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 47741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 47841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Sets the center location in pixels of the gradient. The radius is 47941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * honored only when the gradient type is set to {@link #RADIAL_GRADIENT} 48041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * or {@link #SWEEP_GRADIENT}. 48141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 48241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <strong>Note</strong>: changing this property will affect all instances 4838bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 48441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing this property. 4858bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 48641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @param x the x coordinate of the gradient's center in pixels 48741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @param y the y coordinate of the gradient's center in pixels 4888bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4898bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 4908bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #setGradientType(int) 49141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getGradientCenterX() 49241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getGradientCenterY() 4938bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGradientCenter(float x, float y) { 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.setGradientCenter(x, y); 4963aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 4979891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5008bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 50141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Returns the center X location of this gradient in pixels. 50241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 50341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return the center X location of this gradient in pixels 50441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setGradientCenter(float, float) 50541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 50641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette public float getGradientCenterX() { 50741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette return mGradientState.mCenterX; 50841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 50941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 51041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 51141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Returns the center Y location of this gradient in pixels. 51241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 51341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return the center Y location of this gradient in pixels 51441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setGradientCenter(float, float) 51541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 51641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette public float getGradientCenterY() { 51741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette return mGradientState.mCenterY; 51841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 51941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 52041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 52141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Sets the radius of the gradient. The radius is honored only when the 52241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * gradient type is set to {@link #RADIAL_GRADIENT}. 52341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 52441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <strong>Note</strong>: changing this property will affect all instances 5258bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 52641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing this property. 5278bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 52841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @param gradientRadius the radius of the gradient in pixels 5298bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 5308bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 53117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setGradientType(int) 53241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getGradientRadius() 5338bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGradientRadius(float gradientRadius) { 535861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette mGradientState.setGradientRadius(gradientRadius, TypedValue.COMPLEX_UNIT_PX); 5363aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 5379891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5408bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 541861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette * Returns the radius of the gradient in pixels. The radius is valid only 542861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette * when the gradient type is set to {@link #RADIAL_GRADIENT}. 543861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette * 54441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return the radius of the gradient in pixels 54541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setGradientRadius(float) 546861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette */ 547861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette public float getGradientRadius() { 548861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette if (mGradientState.mGradient != RADIAL_GRADIENT) { 549861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette return 0; 550861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette } 551861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette 552861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette ensureValidRect(); 553861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette return mGradientRadius; 554861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette } 555861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette 556861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette /** 55741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Sets whether or not this drawable will honor its {@code level} property. 55841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 55941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <strong>Note</strong>: changing this property will affect all instances 5608bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 56141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing this property. 5628bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 56341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @param useLevel {@code true} if this drawable should honor its level, 56441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@code false} otherwise 5658bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 5668bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 5670b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette * @see #setLevel(int) 5680b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette * @see #getLevel() 5695f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette * @see #getUseLevel() 5708bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setUseLevel(boolean useLevel) { 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.mUseLevel = useLevel; 5733aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 5749891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 57617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 57741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 57841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Returns whether or not this drawable will honor its {@code level} 57941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * property. 58041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 58141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return {@code true} if this drawable should honor its level, 58241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@code false} otherwise 58341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setUseLevel(boolean) 58441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 5855f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public boolean getUseLevel() { 58641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette return mGradientState.mUseLevel; 58741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 58841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int modulateAlpha(int alpha) { 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int scale = mAlpha + (mAlpha >> 7); 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return alpha * scale >> 8; 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5948bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 5958bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * Returns the orientation of the gradient defined in this drawable. 59641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 59741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return the orientation of the gradient defined in this drawable 59841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setOrientation(Orientation) 5998bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 6008bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy public Orientation getOrientation() { 6018bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy return mGradientState.mOrientation; 6028bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy } 6038bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 6048bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 60541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Sets the orientation of the gradient defined in this drawable. 60641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 60741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <strong>Note</strong>: changing orientation will affect all instances 6088bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 60941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing the orientation. 61017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * 61141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @param orientation the desired orientation (angle) of the gradient 61217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * 61317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #mutate() 61441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getOrientation() 6158bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 6168bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy public void setOrientation(Orientation orientation) { 6178bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy mGradientState.mOrientation = orientation; 6183aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 6198bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy invalidateSelf(); 6208bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy } 6218bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 6228bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 623e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * Sets the colors used to draw the gradient. 624e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * <p> 625e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * Each color is specified as an ARGB integer and the array must contain at 626e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * least 2 colors. 627e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * <p> 628e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * <strong>Note</strong>: changing colors will affect all instances of a 629e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * drawable loaded from a resource. It is recommended to invoke 630e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * {@link #mutate()} before changing the colors. 6318bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 632e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * @param colors an array containing 2 or more ARGB colors 6338bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 63417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setColor(int) 6358bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 63680756e38882720860db52f1fcc21fa1505a02abfTor Norbye public void setColors(@ColorInt int[] colors) { 637e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientState.setGradientColors(colors); 6383aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 6398bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy invalidateSelf(); 6408bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy } 6418bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 64241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 64341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Returns the colors used to draw the gradient, or {@code null} if the 64441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * gradient is drawn using a single color or no colors. 64541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 64641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return the colors used to draw the gradient, or {@code null} 64741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setColors(int[] colors) 64841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 64941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette @Nullable 65041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette public int[] getColors() { 6515f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette return mGradientState.mGradientColors == null ? 6525f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette null : mGradientState.mGradientColors.clone(); 65341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 65441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 65616f1d81d47beb1e04504a76de66e2919dde08c33Alan Viverette public void draw(Canvas canvas) { 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!ensureValidRect()) { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // nothing to draw 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remember the alpha values, in case we temporarily overwrite them 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when we modulate them with mAlpha 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int prevFillAlpha = mFillPaint.getAlpha(); 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int prevStrokeAlpha = mStrokePaint != null ? mStrokePaint.getAlpha() : 0; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the modulate alpha values 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int currFillAlpha = modulateAlpha(prevFillAlpha); 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int currStrokeAlpha = modulateAlpha(prevStrokeAlpha); 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 670e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint != null && 671e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy mStrokePaint.getStrokeWidth() > 0; 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean haveFill = currFillAlpha > 0; 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final GradientState st = mGradientState; 67443027b7bca554818cc4223389747d661819d5706Alan Viverette final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mTintFilter; 67543027b7bca554818cc4223389747d661819d5706Alan Viverette 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* we need a layer iff we're drawing both a fill and stroke, and the 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stroke is non-opaque, and our shapetype actually supports 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fill+stroke. Otherwise we can just draw the stroke (if any) on top 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project of the fill (if any) without worrying about blending artifacts. 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 68143027b7bca554818cc4223389747d661819d5706Alan Viverette final boolean useLayer = haveStroke && haveFill && st.mShape != LINE && 68243027b7bca554818cc4223389747d661819d5706Alan Viverette currStrokeAlpha < 255 && (mAlpha < 255 || colorFilter != null); 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Drawing with a layer is slower than direct drawing, but it 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allows us to apply paint effects like alpha and colorfilter to 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project the result of multiple separate draws. In our case, if the user 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asks for a non-opaque alpha value (via setAlpha), and we're 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stroking, then we need to apply the alpha AFTER we've drawn 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project both the fill and the stroke. 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (useLayer) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLayerPaint == null) { 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayerPaint = new Paint(); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 69507c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mLayerPaint.setDither(st.mDither); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayerPaint.setAlpha(mAlpha); 69743027b7bca554818cc4223389747d661819d5706Alan Viverette mLayerPaint.setColorFilter(colorFilter); 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float rad = mStrokePaint.getStrokeWidth(); 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.saveLayer(mRect.left - rad, mRect.top - rad, 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRect.right + rad, mRect.bottom + rad, 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayerPaint, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't perform the filter in our individual paints 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // since the layer will do it for us 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setColorFilter(null); 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setColorFilter(null); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* if we're not using a layer, apply the dither/filter to our 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project individual paints 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setAlpha(currFillAlpha); 71307c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mFillPaint.setDither(st.mDither); 71443027b7bca554818cc4223389747d661819d5706Alan Viverette mFillPaint.setColorFilter(colorFilter); 715e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (colorFilter != null && st.mSolidColors == null) { 716813680780f365648b39873fa26dfae0123d51aedChet Haase mFillPaint.setColor(mAlpha << 24); 71741c769d9a8858ad20b0a6ed942a1cea19ba59d2dRomain Guy } 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setAlpha(currStrokeAlpha); 72007c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mStrokePaint.setDither(st.mDither); 72143027b7bca554818cc4223389747d661819d5706Alan Viverette mStrokePaint.setColorFilter(colorFilter); 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 724e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (st.mShape) { 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RECTANGLE: 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st.mRadiusArray != null) { 728e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik buildPathIfDirty(); 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawPath(mPath, mFillPaint); 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawPath(mPath, mStrokePaint); 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 73361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy } else if (st.mRadius > 0.0f) { 7344e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed // since the caller is only giving us 1 value, we will force 7354e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed // it to be square if the rect is too small in one dimension 7364e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed // to show it. If we did nothing, Skia would clamp the rad 73761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy // independently along each axis, giving us a thin ellipse 7384e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed // if the rect were very wide but not very tall 739b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik float rad = Math.min(st.mRadius, 740b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik Math.min(mRect.width(), mRect.height()) * 0.5f); 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawRoundRect(mRect, rad, rad, mFillPaint); 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawRoundRect(mRect, rad, rad, mStrokePaint); 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 74561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy } else { 74643027b7bca554818cc4223389747d661819d5706Alan Viverette if (mFillPaint.getColor() != 0 || colorFilter != null || 747cf8675ee176a375f873792684d38a47f78348dffRomain Guy mFillPaint.getShader() != null) { 748cf8675ee176a375f873792684d38a47f78348dffRomain Guy canvas.drawRect(mRect, mFillPaint); 749cf8675ee176a375f873792684d38a47f78348dffRomain Guy } 75061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy if (haveStroke) { 75161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy canvas.drawRect(mRect, mStrokePaint); 75261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy } 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case OVAL: 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawOval(mRect, mFillPaint); 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawOval(mRect, mStrokePaint); 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LINE: { 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RectF r = mRect; 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = r.centerY(); 76471b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette if (haveStroke) { 76571b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette canvas.drawLine(r.left, y, r.right, y, mStrokePaint); 76671b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette } 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RING: 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Path path = buildRing(st); 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawPath(path, mFillPaint); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawPath(path, mStrokePaint); 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 77717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (useLayer) { 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.restore(); 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setAlpha(prevFillAlpha); 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setAlpha(prevStrokeAlpha); 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 787e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 788e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik private void buildPathIfDirty() { 789e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik final GradientState st = mGradientState; 7903aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase if (mPathIsDirty) { 7913aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase ensureValidRect(); 792e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik mPath.reset(); 793e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik mPath.addRoundRect(mRect, st.mRadiusArray, Path.Direction.CW); 7943aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mPathIsDirty = false; 795e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik } 796e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik } 797e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Path buildRing(GradientState st) { 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRingPath != null && (!st.mUseLevelForShape || !mPathIsDirty)) return mRingPath; 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPathIsDirty = false; 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8020b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette float sweep = st.mUseLevelForShape ? (360.0f * getLevel() / 10000.0f) : 360f; 80317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RectF bounds = new RectF(mRect); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = bounds.width() / 2.0f; 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = bounds.height() / 2.0f; 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float thickness = st.mThickness != -1 ? 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st.mThickness : bounds.width() / st.mThicknessRatio; 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // inner radius 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float radius = st.mInnerRadius != -1 ? 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st.mInnerRadius : bounds.width() / st.mInnerRadiusRatio; 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RectF innerBounds = new RectF(bounds); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project innerBounds.inset(x - radius, y - radius); 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds = new RectF(innerBounds); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds.inset(-thickness, -thickness); 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRingPath == null) { 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRingPath = new Path(); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 824b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik mRingPath.reset(); 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Path ringPath = mRingPath; 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // arcTo treats the sweep angle mod 360, so check for that, since we 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // think 360 means draw the entire oval 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sweep < 360 && sweep > -360) { 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.setFillType(Path.FillType.EVEN_ODD); 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // inner top 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.moveTo(x + radius, y); 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // outer top 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.lineTo(x + radius + thickness, y); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // outer arc 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.arcTo(bounds, 0.0f, sweep, false); 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // inner arc 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.arcTo(innerBounds, sweep, -sweep, false); 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.close(); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // add the entire ovals 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.addOval(bounds, Path.Direction.CW); 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.addOval(innerBounds, Path.Direction.CCW); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ringPath; 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8508bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 85141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Changes this drawable to use a single color instead of a gradient. 85241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 85341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <strong>Note</strong>: changing color will affect all instances of a 85441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * drawable loaded from a resource. It is recommended to invoke 85541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing the color. 8568bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 8578bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param argb The color used to fill the shape 8588bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 8598bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 86017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setColors(int[]) 86141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getColor 8628bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 86380756e38882720860db52f1fcc21fa1505a02abfTor Norbye public void setColor(@ColorInt int argb) { 864e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientState.setSolidColors(ColorStateList.valueOf(argb)); 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setColor(argb); 8669891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869519494e207322581075c8ea884fde9d33bb9209eAlan Viverette /** 870519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * Changes this drawable to use a single color state list instead of a 8717c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette * gradient. Calling this method with a null argument will clear the color 8727c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette * and is equivalent to calling {@link #setColor(int)} with the argument 8737c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette * {@link Color#TRANSPARENT}. 874519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * <p> 875519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * <strong>Note</strong>: changing color will affect all instances of a 876519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * drawable loaded from a resource. It is recommended to invoke 877519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * {@link #mutate()} before changing the color.</p> 878519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * 879519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * @param colorStateList The color state list used to fill the shape 88041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 881519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * @see #mutate() 88241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getColor 883519494e207322581075c8ea884fde9d33bb9209eAlan Viverette */ 8845f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setColor(@Nullable ColorStateList colorStateList) { 885e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientState.setSolidColors(colorStateList); 88640df78153987409dbf299b84da9784b69029e184Alan Viverette final int color; 8877c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette if (colorStateList == null) { 88840df78153987409dbf299b84da9784b69029e184Alan Viverette color = Color.TRANSPARENT; 8897c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette } else { 89040df78153987409dbf299b84da9784b69029e184Alan Viverette final int[] stateSet = getState(); 89140df78153987409dbf299b84da9784b69029e184Alan Viverette color = colorStateList.getColorForState(stateSet, 0); 8927c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette } 89340df78153987409dbf299b84da9784b69029e184Alan Viverette mFillPaint.setColor(color); 89440df78153987409dbf299b84da9784b69029e184Alan Viverette invalidateSelf(); 895519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 896519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 89741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 89841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Returns the color state list used to fill the shape, or {@code null} if 89941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * the shape is filled with a gradient or has no fill color. 90041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 90141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return the color state list used to fill this gradient, or {@code null} 90241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 90341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setColor(int) 90441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setColor(ColorStateList) 90541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 9065f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @Nullable 90741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette public ColorStateList getColor() { 90841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette return mGradientState.mSolidColors; 90941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 91041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 911519494e207322581075c8ea884fde9d33bb9209eAlan Viverette @Override 91212b97f5d2b15194ed6673c9838b13c8312157709Alan Viverette protected boolean onStateChange(int[] stateSet) { 913a211dd28b93473c452d68432c602d5209b01c178Alan Viverette boolean invalidateSelf = false; 914a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 915a211dd28b93473c452d68432c602d5209b01c178Alan Viverette final GradientState s = mGradientState; 916e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final ColorStateList solidColors = s.mSolidColors; 917e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (solidColors != null) { 918e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int newColor = solidColors.getColorForState(stateSet, 0); 919519494e207322581075c8ea884fde9d33bb9209eAlan Viverette final int oldColor = mFillPaint.getColor(); 920519494e207322581075c8ea884fde9d33bb9209eAlan Viverette if (oldColor != newColor) { 921519494e207322581075c8ea884fde9d33bb9209eAlan Viverette mFillPaint.setColor(newColor); 922616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette invalidateSelf = true; 923a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 924a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 925a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 926616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette final Paint strokePaint = mStrokePaint; 927616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette if (strokePaint != null) { 928e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final ColorStateList strokeColors = s.mStrokeColors; 929e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (strokeColors != null) { 930e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int newColor = strokeColors.getColorForState(stateSet, 0); 931e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int oldColor = strokePaint.getColor(); 932e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (oldColor != newColor) { 933e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette strokePaint.setColor(newColor); 934616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette invalidateSelf = true; 935616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette } 936519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 937519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 938519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 93943027b7bca554818cc4223389747d661819d5706Alan Viverette if (s.mTint != null && s.mTintMode != null) { 94043027b7bca554818cc4223389747d661819d5706Alan Viverette mTintFilter = updateTintFilter(mTintFilter, s.mTint, s.mTintMode); 94143027b7bca554818cc4223389747d661819d5706Alan Viverette invalidateSelf = true; 94243027b7bca554818cc4223389747d661819d5706Alan Viverette } 94343027b7bca554818cc4223389747d661819d5706Alan Viverette 944a211dd28b93473c452d68432c602d5209b01c178Alan Viverette if (invalidateSelf) { 945a211dd28b93473c452d68432c602d5209b01c178Alan Viverette invalidateSelf(); 946a211dd28b93473c452d68432c602d5209b01c178Alan Viverette return true; 947a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 948a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 949a211dd28b93473c452d68432c602d5209b01c178Alan Viverette return false; 950519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 951519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 952519494e207322581075c8ea884fde9d33bb9209eAlan Viverette @Override 953519494e207322581075c8ea884fde9d33bb9209eAlan Viverette public boolean isStateful() { 954a211dd28b93473c452d68432c602d5209b01c178Alan Viverette final GradientState s = mGradientState; 955a211dd28b93473c452d68432c602d5209b01c178Alan Viverette return super.isStateful() 956e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette || (s.mSolidColors != null && s.mSolidColors.isStateful()) 957e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette || (s.mStrokeColors != null && s.mStrokeColors.isStateful()) 95843027b7bca554818cc4223389747d661819d5706Alan Viverette || (s.mTint != null && s.mTint.isStateful()); 959519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 960519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 962ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette public @Config int getChangingConfigurations() { 963e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return super.getChangingConfigurations() | mGradientState.getChangingConfigurations(); 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9658bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlpha(int alpha) { 9689891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (alpha != mAlpha) { 9699891e1fce5f29d0421d34aa481037417bd70853dChet Haase mAlpha = alpha; 9709891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 9719891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 975b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase public int getAlpha() { 976b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase return mAlpha; 977b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase } 978b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase 979b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase @Override 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDither(boolean dither) { 98107c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette if (dither != mGradientState.mDither) { 98207c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mGradientState.mDither = dither; 9839891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 9849891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 9885f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @Nullable 98938b5f597de96cd892add9017dc810212f549bf68John Spurlock public ColorFilter getColorFilter() { 99038b5f597de96cd892add9017dc810212f549bf68John Spurlock return mColorFilter; 99138b5f597de96cd892add9017dc810212f549bf68John Spurlock } 99238b5f597de96cd892add9017dc810212f549bf68John Spurlock 99338b5f597de96cd892add9017dc810212f549bf68John Spurlock @Override 9945f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setColorFilter(@Nullable ColorFilter colorFilter) { 995bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik if (colorFilter != mColorFilter) { 996bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik mColorFilter = colorFilter; 9979891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 9989891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10025f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setTintList(@Nullable ColorStateList tint) { 100343027b7bca554818cc4223389747d661819d5706Alan Viverette mGradientState.mTint = tint; 100443027b7bca554818cc4223389747d661819d5706Alan Viverette mTintFilter = updateTintFilter(mTintFilter, tint, mGradientState.mTintMode); 100543027b7bca554818cc4223389747d661819d5706Alan Viverette invalidateSelf(); 100643027b7bca554818cc4223389747d661819d5706Alan Viverette } 100743027b7bca554818cc4223389747d661819d5706Alan Viverette 100843027b7bca554818cc4223389747d661819d5706Alan Viverette @Override 10095f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setTintMode(@Nullable PorterDuff.Mode tintMode) { 101043027b7bca554818cc4223389747d661819d5706Alan Viverette mGradientState.mTintMode = tintMode; 101143027b7bca554818cc4223389747d661819d5706Alan Viverette mTintFilter = updateTintFilter(mTintFilter, mGradientState.mTint, tintMode); 101243027b7bca554818cc4223389747d661819d5706Alan Viverette invalidateSelf(); 101343027b7bca554818cc4223389747d661819d5706Alan Viverette } 101443027b7bca554818cc4223389747d661819d5706Alan Viverette 101543027b7bca554818cc4223389747d661819d5706Alan Viverette @Override 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 1017888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return (mAlpha == 255 && mGradientState.mOpaqueOverBounds && isOpaqueForState()) ? 10180a1c6f021be032f5aecb341c2794efb06c0a8a0dAlan Viverette PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT; 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onBoundsChange(Rect r) { 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onBoundsChange(r); 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRingPath = null; 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPathIsDirty = true; 10263aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10300b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette protected boolean onLevelChange(int level) { 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onLevelChange(level); 10323aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPathIsDirty = true; 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidateSelf(); 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10393aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase * This checks mGradientIsDirty, and if it is true, recomputes both our drawing 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rectangle (mRect) and the gradient itself, since it depends on our 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rectangle too. 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the resulting rectangle is not empty, false otherwise 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean ensureValidRect() { 10453aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase if (mGradientIsDirty) { 10463aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = false; 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect bounds = getBounds(); 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float inset = 0; 105017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStrokePaint != null) { 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inset = mStrokePaint.getStrokeWidth() * 0.5f; 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final GradientState st = mGradientState; 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRect.set(bounds.left + inset, bounds.top + inset, 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds.right - inset, bounds.bottom - inset); 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1060e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int[] gradientColors = st.mGradientColors; 1061e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (gradientColors != null) { 1062e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final RectF r = mRect; 1063e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final float x0, x1, y0, y1; 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st.mGradient == LINEAR_GRADIENT) { 10660b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette final float level = st.mUseLevel ? getLevel() / 10000.0f : 1.0f; 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (st.mOrientation) { 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case TOP_BOTTOM: 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.top; 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = x0; y1 = level * r.bottom; 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case TR_BL: 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.right; y0 = r.top; 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.left; y1 = level * r.bottom; 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RIGHT_LEFT: 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.right; y0 = r.top; 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.left; y1 = y0; 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case BR_TL: 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.right; y0 = r.bottom; 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.left; y1 = level * r.top; 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case BOTTOM_TOP: 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.bottom; 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = x0; y1 = level * r.top; 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case BL_TR: 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.bottom; 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.right; y1 = level * r.top; 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LEFT_RIGHT: 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.top; 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.right; y1 = y0; 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default:/* TL_BR */ 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.top; 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.right; y1 = level * r.bottom; 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setShader(new LinearGradient(x0, y0, x1, y1, 1103e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette gradientColors, st.mPositions, Shader.TileMode.CLAMP)); 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (st.mGradient == RADIAL_GRADIENT) { 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left + (r.right - r.left) * st.mCenterX; 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y0 = r.top + (r.bottom - r.top) * st.mCenterY; 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1108861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette float radius = st.mGradientRadius; 1109b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION) { 1110b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette // Fall back to parent width or height if intrinsic 1111b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette // size is not specified. 1112b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette final float width = st.mWidth >= 0 ? st.mWidth : r.width(); 1113b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette final float height = st.mHeight >= 0 ? st.mHeight : r.height(); 1114b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette radius *= Math.min(width, height); 1115b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette } else if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION_PARENT) { 1116861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette radius *= Math.min(r.width(), r.height()); 1117861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette } 1118b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 1119861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette if (st.mUseLevel) { 11200b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette radius *= getLevel() / 10000.0f; 1121861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette } 1122b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 1123861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette mGradientRadius = radius; 1124b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 1125b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette if (radius <= 0) { 1126b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette // We can't have a shader with non-positive radius, so 1127b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette // let's have a very, very small radius. 1128b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette radius = 0.001f; 1129b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette } 1130b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 1131861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette mFillPaint.setShader(new RadialGradient( 1132e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette x0, y0, radius, gradientColors, null, Shader.TileMode.CLAMP)); 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (st.mGradient == SWEEP_GRADIENT) { 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left + (r.right - r.left) * st.mCenterX; 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y0 = r.top + (r.bottom - r.top) * st.mCenterY; 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1137e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette int[] tempColors = gradientColors; 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] tempPositions = null; 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st.mUseLevel) { 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempColors = st.mTempColors; 1142e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int length = gradientColors.length; 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tempColors == null || tempColors.length != length + 1) { 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempColors = st.mTempColors = new int[length + 1]; 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1146e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette System.arraycopy(gradientColors, 0, tempColors, 0, length); 1147e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette tempColors[length] = gradientColors[length - 1]; 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempPositions = st.mTempPositions; 115052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float fraction = 1.0f / (length - 1); 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tempPositions == null || tempPositions.length != length + 1) { 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempPositions = st.mTempPositions = new float[length + 1]; 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11550b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette final float level = getLevel() / 10000.0f; 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < length; i++) { 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempPositions[i] = i * fraction * level; 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempPositions[length] = 1.0f; 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setShader(new SweepGradient(x0, y0, tempColors, tempPositions)); 11634d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette } 11644d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette 11654d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette // If we don't have a solid color, the alpha channel must be 11664d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette // maxed out so that alpha modulation works correctly. 1167e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (st.mSolidColors == null) { 11684d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette mFillPaint.setColor(Color.BLACK); 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return !mRect.isEmpty(); 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1176ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser, 1177ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette @NonNull AttributeSet attrs, @Nullable Theme theme) 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 1179ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette super.inflate(r, parser, attrs, theme); 1180ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 1181ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientState.setDensity(Drawable.resolveDensity(r, 0)); 1182ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 118352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawable); 118417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateStateFromTypedArray(a); 118552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 118652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 118752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette inflateChildElements(r, parser, attrs, theme); 118852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 118945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(r); 119052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 119152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 119252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 1193ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette public void applyTheme(@NonNull Theme t) { 119452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette super.applyTheme(t); 119552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 119652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final GradientState state = mGradientState; 119717cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette if (state == null) { 119817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette return; 119952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 120052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 1201ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette state.setDensity(Drawable.resolveDensity(t.getResources(), 0)); 1202ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 120317cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette if (state.mThemeAttrs != null) { 120417cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette final TypedArray a = t.resolveAttributes( 120517cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette state.mThemeAttrs, R.styleable.GradientDrawable); 120617cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette updateStateFromTypedArray(a); 120717cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette a.recycle(); 120817cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette } 120952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 121045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (state.mTint != null && state.mTint.canApplyTheme()) { 1211e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette state.mTint = state.mTint.obtainForTheme(t); 121245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 121345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 1214e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mSolidColors != null && state.mSolidColors.canApplyTheme()) { 1215e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette state.mSolidColors = state.mSolidColors.obtainForTheme(t); 121645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 121745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 1218e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mStrokeColors != null && state.mStrokeColors.canApplyTheme()) { 1219e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette state.mStrokeColors = state.mStrokeColors.obtainForTheme(t); 122045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 122145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 122217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette applyThemeChildElements(t); 122352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 122445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(t.getResources()); 122552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 122652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 122752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette /** 122852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * Updates the constant state from the values in the typed array. 122952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette */ 123052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private void updateStateFromTypedArray(TypedArray a) { 123152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final GradientState state = mGradientState; 123252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 12338e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 12348e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= a.getChangingConfigurations(); 12358e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 123617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // Extract the theme attributes, if any. 123717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mThemeAttrs = a.extractThemeAttrs(); 123852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 123917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mShape = a.getInt(R.styleable.GradientDrawable_shape, state.mShape); 124007c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette state.mDither = a.getBoolean(R.styleable.GradientDrawable_dither, state.mDither); 124152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 124252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (state.mShape == RING) { 124317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mInnerRadius = a.getDimensionPixelSize( 124417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_innerRadius, state.mInnerRadius); 124552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 124617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (state.mInnerRadius == -1) { 124752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette state.mInnerRadiusRatio = a.getFloat( 124817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_innerRadiusRatio, state.mInnerRadiusRatio); 124952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 125052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 125117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mThickness = a.getDimensionPixelSize( 125217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_thickness, state.mThickness); 125352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 125417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (state.mThickness == -1) { 125552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette state.mThicknessRatio = a.getFloat( 125617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_thicknessRatio, state.mThicknessRatio); 125752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 125852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 125917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mUseLevelForShape = a.getBoolean( 126017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_useLevel, state.mUseLevelForShape); 126152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 126243027b7bca554818cc4223389747d661819d5706Alan Viverette 126343027b7bca554818cc4223389747d661819d5706Alan Viverette final int tintMode = a.getInt(R.styleable.GradientDrawable_tintMode, -1); 126443027b7bca554818cc4223389747d661819d5706Alan Viverette if (tintMode != -1) { 126543027b7bca554818cc4223389747d661819d5706Alan Viverette state.mTintMode = Drawable.parseTintMode(tintMode, PorterDuff.Mode.SRC_IN); 126643027b7bca554818cc4223389747d661819d5706Alan Viverette } 126743027b7bca554818cc4223389747d661819d5706Alan Viverette 126843027b7bca554818cc4223389747d661819d5706Alan Viverette final ColorStateList tint = a.getColorStateList(R.styleable.GradientDrawable_tint); 126943027b7bca554818cc4223389747d661819d5706Alan Viverette if (tint != null) { 127043027b7bca554818cc4223389747d661819d5706Alan Viverette state.mTint = tint; 127143027b7bca554818cc4223389747d661819d5706Alan Viverette } 127287e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette 127387e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette final int insetLeft = a.getDimensionPixelSize( 127487e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette R.styleable.GradientDrawable_opticalInsetLeft, state.mOpticalInsets.left); 127587e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette final int insetTop = a.getDimensionPixelSize( 127687e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette R.styleable.GradientDrawable_opticalInsetTop, state.mOpticalInsets.top); 127787e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette final int insetRight = a.getDimensionPixelSize( 127887e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette R.styleable.GradientDrawable_opticalInsetRight, state.mOpticalInsets.right); 127987e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette final int insetBottom = a.getDimensionPixelSize( 128087e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette R.styleable.GradientDrawable_opticalInsetBottom, state.mOpticalInsets.bottom); 128187e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette state.mOpticalInsets = Insets.of(insetLeft, insetTop, insetRight, insetBottom); 128252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 128352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 128452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 128552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public boolean canApplyTheme() { 1286d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette return (mGradientState != null && mGradientState.canApplyTheme()) || super.canApplyTheme(); 128752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 128852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 128952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private void applyThemeChildElements(Theme t) { 129017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 129152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 129217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrSize != null) { 129317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 129417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrSize, R.styleable.GradientDrawableSize); 129517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableSize(a); 129652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 129752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 129852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 129917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrGradient != null) { 130017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 130117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrGradient, R.styleable.GradientDrawableGradient); 130217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette try { 130317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableGradient(t.getResources(), a); 130417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } catch (XmlPullParserException e) { 1305c078c605ab904b0e4a5d793cbeffd78c340f2816Alan Viverette rethrowAsRuntimeException(e); 130617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } finally { 130717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a.recycle(); 130817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } 130952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 131052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 131117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrSolid != null) { 131217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 131317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrSolid, R.styleable.GradientDrawableSolid); 131417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableSolid(a); 131552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 131652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 131752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 131817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrStroke != null) { 131917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 132017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrStroke, R.styleable.GradientDrawableStroke); 132117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableStroke(a); 132252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 132352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 132452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 132517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrCorners != null) { 132617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 132717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrCorners, R.styleable.DrawableCorners); 132817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateDrawableCorners(a); 132952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 133052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 133152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 133217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrPadding != null) { 133317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 133417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrPadding, R.styleable.GradientDrawablePadding); 133517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawablePadding(a); 133652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 133752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 133852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 133952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 134052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs, 134152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette Theme theme) throws XmlPullParserException, IOException { 134252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette TypedArray a; 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int type; 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1345ed7894352f8addfe3d0da75cc7fe8bc6fef201dcRomain Guy final int innerDepth = parser.getDepth() + 1; 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int depth; 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((depth=parser.getDepth()) >= innerDepth 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || type != XmlPullParser.END_TAG)) { 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != XmlPullParser.START_TAG) { 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (depth > innerDepth) { 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 135752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = parser.getName(); 135917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name.equals("size")) { 136117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableSize); 136217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableSize(a); 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("gradient")) { 136517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableGradient); 136617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableGradient(r, a); 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("solid")) { 136917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableSolid); 137017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableSolid(a); 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("stroke")) { 137317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableStroke); 137417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableStroke(a); 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("corners")) { 137717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.DrawableCorners); 137817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateDrawableCorners(a); 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("padding")) { 138117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawablePadding); 138217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawablePadding(a); 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("drawable", "Bad element under <shape>: " + name); 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 138752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 138852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 138952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 139017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawablePadding(TypedArray a) { 139117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 139252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 13938e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 13948e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 13958e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 139652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // Extract the theme attributes, if any. 139717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrPadding = a.extractThemeAttrs(); 139817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1399982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette if (st.mPadding == null) { 1400982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette st.mPadding = new Rect(); 1401982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette } 1402982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette 140317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final Rect pad = st.mPadding; 140417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette pad.set(a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_left, pad.left), 140517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_top, pad.top), 140617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_right, pad.right), 140717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_bottom, pad.bottom)); 140817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette mPadding = pad; 140952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 1410e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 141117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateDrawableCorners(TypedArray a) { 141217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 141317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 14148e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 14158e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 14168e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 141717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // Extract the theme attributes, if any. 141817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrCorners = a.extractThemeAttrs(); 141917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 142017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int radius = a.getDimensionPixelSize( 142117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.DrawableCorners_radius, (int) st.mRadius); 142252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setCornerRadius(radius); 142317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 142417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // TODO: Update these to be themeable. 142517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int topLeftRadius = a.getDimensionPixelSize( 142652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.DrawableCorners_topLeftRadius, radius); 142717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int topRightRadius = a.getDimensionPixelSize( 142852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.DrawableCorners_topRightRadius, radius); 142917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int bottomLeftRadius = a.getDimensionPixelSize( 143052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.DrawableCorners_bottomLeftRadius, radius); 143117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int bottomRightRadius = a.getDimensionPixelSize( 143252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.DrawableCorners_bottomRightRadius, radius); 143352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (topLeftRadius != radius || topRightRadius != radius || 143452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette bottomLeftRadius != radius || bottomRightRadius != radius) { 143552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // The corner radii are specified in clockwise order (see Path.addRoundRect()) 143652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setCornerRadii(new float[] { 143752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette topLeftRadius, topLeftRadius, 143852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette topRightRadius, topRightRadius, 143952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette bottomRightRadius, bottomRightRadius, 144052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette bottomLeftRadius, bottomLeftRadius 144152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette }); 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 144352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 144452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 144517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawableStroke(TypedArray a) { 144617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 144717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 14488e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 14498e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 14508e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 14518e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Extract the theme attributes, if any. 145217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrStroke = a.extractThemeAttrs(); 145317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 14543b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette // We have an explicit stroke defined, so the default stroke width 14553b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette // must be at least 0 or the current stroke width. 14563b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final int defaultStrokeWidth = Math.max(0, st.mStrokeWidth); 145752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int width = a.getDimensionPixelSize( 14583b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette R.styleable.GradientDrawableStroke_width, defaultStrokeWidth); 145952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float dashWidth = a.getDimension( 146017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableStroke_dashWidth, st.mStrokeDashWidth); 146117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 146217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette ColorStateList colorStateList = a.getColorStateList( 146317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableStroke_color); 146417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (colorStateList == null) { 1465e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette colorStateList = st.mStrokeColors; 146617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } 146717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 146852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (dashWidth != 0.0f) { 146952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float dashGap = a.getDimension( 147017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableStroke_dashGap, st.mStrokeDashGap); 147152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setStroke(width, colorStateList, dashWidth, dashGap); 147252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 147352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setStroke(width, colorStateList); 147452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 147552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 147652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 147717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawableSolid(TypedArray a) { 14788e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final GradientState st = mGradientState; 14798e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 14808e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 14818e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 14828e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 14838e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Extract the theme attributes, if any. 14848e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mAttrSolid = a.extractThemeAttrs(); 148517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 148652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final ColorStateList colorStateList = a.getColorStateList( 148752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableSolid_color); 148817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (colorStateList != null) { 148917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette setColor(colorStateList); 149017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } 149152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 149252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 149317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawableGradient(Resources r, TypedArray a) 149452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette throws XmlPullParserException { 149552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final GradientState st = mGradientState; 149617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 14978e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 14988e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 14998e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 150017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // Extract the theme attributes, if any. 150117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrGradient = a.extractThemeAttrs(); 150217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 150317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mCenterX = getFloatOrFraction( 150417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a, R.styleable.GradientDrawableGradient_centerX, st.mCenterX); 150517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mCenterY = getFloatOrFraction( 150617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a, R.styleable.GradientDrawableGradient_centerY, st.mCenterY); 150717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mUseLevel = a.getBoolean( 150817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableGradient_useLevel, st.mUseLevel); 150917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mGradient = a.getInt( 151017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableGradient_type, st.mGradient); 151117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 151217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // TODO: Update these to be themeable. 151352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int startColor = a.getColor( 151452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableGradient_startColor, 0); 151552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final boolean hasCenterColor = a.hasValue( 151652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableGradient_centerColor); 151752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int centerColor = a.getColor( 151852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableGradient_centerColor, 0); 151952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int endColor = a.getColor( 152052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableGradient_endColor, 0); 152152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 152252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (hasCenterColor) { 1523e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors = new int[3]; 1524e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[0] = startColor; 1525e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[1] = centerColor; 1526e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[2] = endColor; 152717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 152852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mPositions = new float[3]; 152952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mPositions[0] = 0.0f; 153052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // Since 0.5f is default value, try to take the one that isn't 0.5f 153152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mPositions[1] = st.mCenterX != 0.5f ? st.mCenterX : st.mCenterY; 153252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mPositions[2] = 1f; 153352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 1534e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors = new int[2]; 1535e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[0] = startColor; 1536e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[1] = endColor; 153752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 153852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 153952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (st.mGradient == LINEAR_GRADIENT) { 154017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle); 154152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette angle %= 360; 154252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 154352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (angle % 45 != 0) { 154452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette throw new XmlPullParserException(a.getPositionDescription() 154552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette + "<gradient> tag requires 'angle' attribute to " 154652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette + "be a multiple of 45"); 154752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 154852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 154917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAngle = angle; 155017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 155152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette switch (angle) { 155252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 0: 155352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.LEFT_RIGHT; 155452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 155552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 45: 155652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.BL_TR; 155752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 155852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 90: 155952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.BOTTOM_TOP; 156052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 156152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 135: 156252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.BR_TL; 156352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 156452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 180: 156552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.RIGHT_LEFT; 156652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 156752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 225: 156852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.TR_BL; 156952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 157052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 270: 157152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.TOP_BOTTOM; 157252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 157352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 315: 157452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.TL_BR; 157552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 157652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 157752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 157817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius); 157952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (tv != null) { 158052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float radius; 15815f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette final @RadiusType int radiusType; 158252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (tv.type == TypedValue.TYPE_FRACTION) { 158352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radius = tv.getFraction(1.0f, 1.0f); 158452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 158552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT) 158652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette & TypedValue.COMPLEX_UNIT_MASK; 158752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) { 158852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radiusType = RADIUS_TYPE_FRACTION_PARENT; 158952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 159052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radiusType = RADIUS_TYPE_FRACTION; 159152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 15922efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette } else if (tv.type == TypedValue.TYPE_DIMENSION) { 159352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radius = tv.getDimension(r.getDisplayMetrics()); 159452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radiusType = RADIUS_TYPE_PIXELS; 15952efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette } else { 15962efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette radius = tv.getFloat(); 15972efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette radiusType = RADIUS_TYPE_PIXELS; 159852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 159952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 160052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mGradientRadius = radius; 160152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mGradientRadiusType = radiusType; 160252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else if (st.mGradient == RADIAL_GRADIENT) { 160352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette throw new XmlPullParserException( 160452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.getPositionDescription() 160552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette + "<gradient> tag requires 'gradientRadius' " 160652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette + "attribute with radial type"); 160752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 160852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 160952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 161052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 161117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawableSize(TypedArray a) { 161217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 161352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 16148e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 16158e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 16168e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 161752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // Extract the theme attributes, if any. 161817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrSize = a.extractThemeAttrs(); 161917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 162017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mWidth = a.getDimensionPixelSize(R.styleable.GradientDrawableSize_width, st.mWidth); 162117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mHeight = a.getDimensionPixelSize(R.styleable.GradientDrawableSize_height, st.mHeight); 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static float getFloatOrFraction(TypedArray a, int index, float defaultValue) { 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedValue tv = a.peekValue(index); 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v = defaultValue; 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tv != null) { 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean vIsFraction = tv.type == TypedValue.TYPE_FRACTION; 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v = vIsFraction ? tv.getFraction(1.0f, 1.0f) : tv.getFloat(); 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return v; 16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 163317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicWidth() { 16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mGradientState.mWidth; 16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicHeight() { 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mGradientState.mHeight; 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 164317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 164487e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette /** @hide */ 164587e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette @Override 164687e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette public Insets getOpticalInsets() { 164787e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette return mGradientState.mOpticalInsets; 164887e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette } 164987e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ConstantState getConstantState() { 16526efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais mGradientState.mChangingConfigurations = getChangingConfigurations(); 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mGradientState; 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1656888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette private boolean isOpaqueForState() { 1657888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette if (mGradientState.mStrokeWidth >= 0 && mStrokePaint != null 1658888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette && !isOpaque(mStrokePaint.getColor())) { 1659888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return false; 1660888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette } 1661888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette 16625f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette // Don't check opacity if we're using a gradient, as we've already 16635f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette // checked the gradient opacity in mOpaqueOverShape. 16645f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette if (mGradientState.mGradientColors == null && !isOpaque(mFillPaint.getColor())) { 1665888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return false; 1666888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette } 1667888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette 1668888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return true; 1669888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette } 1670888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 167231ba192dd201df2cad96a8c503f730130ab0d80fChris Craik public void getOutline(Outline outline) { 1673b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik final GradientState st = mGradientState; 1674b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik final Rect bounds = getBounds(); 1675f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik // only report non-zero alpha if shape being drawn has consistent opacity over shape. Must 1676f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik // either not have a stroke, or have same stroke/fill opacity 1677f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik boolean useFillOpacity = st.mOpaqueOverShape && (mGradientState.mStrokeWidth <= 0 1678f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik || mStrokePaint == null 1679f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik || mStrokePaint.getAlpha() == mFillPaint.getAlpha()); 1680f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik outline.setAlpha(useFillOpacity 1681f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik ? modulateAlpha(mFillPaint.getAlpha()) / 255.0f 1682f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik : 0.0f); 1683b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik 1684b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik switch (st.mShape) { 1685b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik case RECTANGLE: 1686b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik if (st.mRadiusArray != null) { 1687e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik buildPathIfDirty(); 1688e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik outline.setConvexPath(mPath); 168931ba192dd201df2cad96a8c503f730130ab0d80fChris Craik return; 1690b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik } 1691e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 1692b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik float rad = 0; 1693b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik if (st.mRadius > 0.0f) { 1694b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik // clamp the radius based on width & height, matching behavior in draw() 1695b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik rad = Math.min(st.mRadius, 1696b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik Math.min(bounds.width(), bounds.height()) * 0.5f); 1697b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik } 16987979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik outline.setRoundRect(bounds, rad); 169931ba192dd201df2cad96a8c503f730130ab0d80fChris Craik return; 17007979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik case OVAL: 17017979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik outline.setOval(bounds); 170231ba192dd201df2cad96a8c503f730130ab0d80fChris Craik return; 17037979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik case LINE: 17043b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette // Hairlines (0-width stroke) must have a non-empty outline for 17053b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette // shadows to draw correctly, so we'll use a very small width. 17063b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final float halfStrokeWidth = mStrokePaint == null ? 17073b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette 0.0001f : mStrokePaint.getStrokeWidth() * 0.5f; 17083b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final float centerY = bounds.centerY(); 17093b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final int top = (int) Math.floor(centerY - halfStrokeWidth); 17103b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final int bottom = (int) Math.ceil(centerY + halfStrokeWidth); 1711b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik 1712e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik outline.setRect(bounds.left, top, bounds.right, bottom); 171331ba192dd201df2cad96a8c503f730130ab0d80fChris Craik return; 1714b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik default: 171531ba192dd201df2cad96a8c503f730130ab0d80fChris Craik // TODO: support more complex shapes 1716b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik } 1717b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik } 1718b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik 1719b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik @Override 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable mutate() { 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mMutated && super.mutate() == this) { 1722ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientState = new GradientState(mGradientState, null); 172345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(null); 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutated = true; 17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette /** 1730727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette * @hide 1731727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette */ 1732727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette public void clearMutated() { 1733727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette super.clearMutated(); 1734727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mMutated = false; 1735727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 1736727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final static class GradientState extends ConstantState { 1738ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette public @Config int mChangingConfigurations; 17395f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public @Shape int mShape = RECTANGLE; 17405f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public @GradientType int mGradient = LINEAR_GRADIENT; 174171b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public int mAngle = 0; 17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Orientation mOrientation; 1743e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public ColorStateList mSolidColors; 1744e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public ColorStateList mStrokeColors; 17455f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public @ColorInt int[] mGradientColors; 17465f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public @ColorInt int[] mTempColors; // no need to copy 17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float[] mTempPositions; // no need to copy 17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float[] mPositions; 174971b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public int mStrokeWidth = -1; // if >= 0 use stroking. 175071b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public float mStrokeDashWidth = 0.0f; 175171b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public float mStrokeDashGap = 0.0f; 175271b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public float mRadius = 0.0f; // use this if mRadiusArray is null 175371b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public float[] mRadiusArray = null; 175471b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public Rect mPadding = null; 17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mWidth = -1; 17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mHeight = -1; 175717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public float mInnerRadiusRatio = DEFAULT_INNER_RADIUS_RATIO; 175817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public float mThicknessRatio = DEFAULT_THICKNESS_RATIO; 175917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public int mInnerRadius = -1; 176017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public int mThickness = -1; 176107c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette public boolean mDither = false; 176287e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette public Insets mOpticalInsets = Insets.NONE; 176307c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette 1764969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette float mCenterX = 0.5f; 1765969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette float mCenterY = 0.5f; 1766969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette float mGradientRadius = 0.5f; 17675f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @RadiusType int mGradientRadiusType = RADIUS_TYPE_PIXELS; 1768969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette boolean mUseLevel = false; 1769969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette boolean mUseLevelForShape = true; 1770969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette 1771969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette boolean mOpaqueOverBounds; 1772969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette boolean mOpaqueOverShape; 17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 177443027b7bca554818cc4223389747d661819d5706Alan Viverette ColorStateList mTint = null; 177543027b7bca554818cc4223389747d661819d5706Alan Viverette PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE; 177643027b7bca554818cc4223389747d661819d5706Alan Viverette 1777ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette int mDensity = DisplayMetrics.DENSITY_DEFAULT; 1778ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 177952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mThemeAttrs; 178052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrSize; 178152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrGradient; 178252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrSolid; 178352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrStroke; 178452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrCorners; 178552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrPadding; 178652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 1787e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public GradientState(Orientation orientation, int[] gradientColors) { 17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOrientation = orientation; 1789e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette setGradientColors(gradientColors); 17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1792ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette public GradientState(@NonNull GradientState orig, @Nullable Resources res) { 1793ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mChangingConfigurations = orig.mChangingConfigurations; 1794ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mShape = orig.mShape; 1795ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradient = orig.mGradient; 1796ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAngle = orig.mAngle; 1797ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOrientation = orig.mOrientation; 1798ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mSolidColors = orig.mSolidColors; 1799ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (orig.mGradientColors != null) { 1800ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientColors = orig.mGradientColors.clone(); 1801562bf17c6c7c5226b2220e27a1543d4a43543d6cPhil Dubach } 1802ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (orig.mPositions != null) { 1803ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPositions = orig.mPositions.clone(); 18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1805ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeColors = orig.mStrokeColors; 1806ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeWidth = orig.mStrokeWidth; 1807ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeDashWidth = orig.mStrokeDashWidth; 1808ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeDashGap = orig.mStrokeDashGap; 1809ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadius = orig.mRadius; 1810ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (orig.mRadiusArray != null) { 1811ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadiusArray = orig.mRadiusArray.clone(); 18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1813ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (orig.mPadding != null) { 1814ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding = new Rect(orig.mPadding); 1815ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1816ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mWidth = orig.mWidth; 1817ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mHeight = orig.mHeight; 1818ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mInnerRadiusRatio = orig.mInnerRadiusRatio; 1819ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mThicknessRatio = orig.mThicknessRatio; 1820ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mInnerRadius = orig.mInnerRadius; 1821ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mThickness = orig.mThickness; 1822ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mDither = orig.mDither; 1823ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpticalInsets = orig.mOpticalInsets; 1824ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mCenterX = orig.mCenterX; 1825ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mCenterY = orig.mCenterY; 1826ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientRadius = orig.mGradientRadius; 1827ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientRadiusType = orig.mGradientRadiusType; 1828ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mUseLevel = orig.mUseLevel; 1829ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mUseLevelForShape = orig.mUseLevelForShape; 1830ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpaqueOverBounds = orig.mOpaqueOverBounds; 1831ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpaqueOverShape = orig.mOpaqueOverShape; 1832ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mTint = orig.mTint; 1833ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mTintMode = orig.mTintMode; 1834ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mThemeAttrs = orig.mThemeAttrs; 1835ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAttrSize = orig.mAttrSize; 1836ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAttrGradient = orig.mAttrGradient; 1837ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAttrSolid = orig.mAttrSolid; 1838ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAttrStroke = orig.mAttrStroke; 1839ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAttrCorners = orig.mAttrCorners; 1840ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAttrPadding = orig.mAttrPadding; 1841ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 1842ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mDensity = Drawable.resolveDensity(res, orig.mDensity); 1843ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (orig.mDensity != mDensity) { 1844ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette applyDensityScaling(orig.mDensity, mDensity); 1845ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1846ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1847ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 1848ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette /** 1849ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * Sets the constant state density. 1850ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * <p> 1851ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * If the density has been previously set, dispatches the change to 1852ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * subclasses so that density-dependent properties may be scaled as 1853ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * necessary. 1854ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * 1855ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * @param targetDensity the new constant state density 1856ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette */ 1857ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette public final void setDensity(int targetDensity) { 1858ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mDensity != targetDensity) { 1859ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final int sourceDensity = mDensity; 1860ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mDensity = targetDensity; 1861ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 1862ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette applyDensityScaling(sourceDensity, targetDensity); 1863ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1864ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1865ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 1866ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette private void applyDensityScaling(int sourceDensity, int targetDensity) { 1867ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mInnerRadius > 0) { 1868ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mInnerRadius = Drawable.scaleFromDensity( 1869ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mInnerRadius, sourceDensity, targetDensity, true); 1870ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1871ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mThickness > 0) { 1872ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mThickness = Drawable.scaleFromDensity( 1873ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mThickness, sourceDensity, targetDensity, true); 1874ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1875ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mOpticalInsets != Insets.NONE) { 1876ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final int left = Drawable.scaleFromDensity( 1877ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpticalInsets.left, sourceDensity, targetDensity, true); 1878ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final int top = Drawable.scaleFromDensity( 1879ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpticalInsets.top, sourceDensity, targetDensity, true); 1880ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final int right = Drawable.scaleFromDensity( 1881ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpticalInsets.right, sourceDensity, targetDensity, true); 1882ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final int bottom = Drawable.scaleFromDensity( 1883ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpticalInsets.bottom, sourceDensity, targetDensity, true); 1884ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpticalInsets = Insets.of(left, top, right, bottom); 1885ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1886ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mPadding != null) { 1887ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.left = Drawable.scaleFromDensity( 1888ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.left, sourceDensity, targetDensity, false); 1889ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.top = Drawable.scaleFromDensity( 1890ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.top, sourceDensity, targetDensity, false); 1891ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.right = Drawable.scaleFromDensity( 1892ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.right, sourceDensity, targetDensity, false); 1893ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.bottom = Drawable.scaleFromDensity( 1894ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.bottom, sourceDensity, targetDensity, false); 1895ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1896ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mRadius > 0) { 1897ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadius = Drawable.scaleFromDensity(mRadius, sourceDensity, targetDensity); 1898ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1899ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mRadiusArray != null) { 1900ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadiusArray[0] = Drawable.scaleFromDensity( 1901ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette (int) mRadiusArray[0], sourceDensity, targetDensity, true); 1902ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadiusArray[1] = Drawable.scaleFromDensity( 1903ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette (int) mRadiusArray[1], sourceDensity, targetDensity, true); 1904ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadiusArray[2] = Drawable.scaleFromDensity( 1905ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette (int) mRadiusArray[2], sourceDensity, targetDensity, true); 1906ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadiusArray[3] = Drawable.scaleFromDensity( 1907ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette (int) mRadiusArray[3], sourceDensity, targetDensity, true); 1908ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1909ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mStrokeWidth > 0) { 1910ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeWidth = Drawable.scaleFromDensity( 1911ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeWidth, sourceDensity, targetDensity, true); 1912ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1913ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mStrokeDashWidth > 0) { 1914ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeDashWidth = Drawable.scaleFromDensity( 1915ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeDashGap, sourceDensity, targetDensity); 1916ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1917ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mStrokeDashGap > 0) { 1918ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeDashGap = Drawable.scaleFromDensity( 1919ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeDashGap, sourceDensity, targetDensity); 1920ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1921ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mGradientRadiusType == RADIUS_TYPE_PIXELS) { 1922ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientRadius = Drawable.scaleFromDensity( 1923ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientRadius, sourceDensity, targetDensity); 1924ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1925ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mWidth > 0) { 1926ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mWidth = Drawable.scaleFromDensity(mWidth, sourceDensity, targetDensity, true); 1927ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1928ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mHeight > 0) { 1929ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mHeight = Drawable.scaleFromDensity(mHeight, sourceDensity, targetDensity, true); 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 193152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 193252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 193352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 193452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public boolean canApplyTheme() { 193545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return mThemeAttrs != null 193645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || mAttrSize != null || mAttrGradient != null 193745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || mAttrSolid != null || mAttrStroke != null 193845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || mAttrCorners != null || mAttrPadding != null 193945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || (mTint != null && mTint.canApplyTheme()) 1940e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette || (mStrokeColors != null && mStrokeColors.canApplyTheme()) 1941e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette || (mSolidColors != null && mSolidColors.canApplyTheme()) 194245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || super.canApplyTheme(); 19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable newDrawable() { 194745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return new GradientDrawable(this, null); 19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 194917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1951ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette public Drawable newDrawable(@Nullable Resources res) { 1952ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette // If this drawable is being created for a different density, 1953ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette // just create a new constant state and call it a day. 1954ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final GradientState state; 1955ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final int density = Drawable.resolveDensity(res, mDensity); 1956ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (density != mDensity) { 1957ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette state = new GradientState(this, res); 1958ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } else { 1959ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette state = this; 1960ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1961ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 1962ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette return new GradientDrawable(state, res); 1963c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 196417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1965c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn @Override 1966ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette public @Config int getChangingConfigurations() { 1967e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return mChangingConfigurations 1968e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette | (mStrokeColors != null ? mStrokeColors.getChangingConfigurations() : 0) 1969e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette | (mSolidColors != null ? mSolidColors.getChangingConfigurations() : 0) 1970e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette | (mTint != null ? mTint.getChangingConfigurations() : 0); 19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19735f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setShape(@Shape int shape) { 19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShape = shape; 1975e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy computeOpacity(); 19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19785f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setGradientType(@GradientType int gradient) { 19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradient = gradient; 19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGradientCenter(float x, float y) { 19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCenterX = x; 19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCenterY = y; 19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19875f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setGradientColors(@Nullable int[] colors) { 1988e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientColors = colors; 1989e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mSolidColors = null; 1990e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy computeOpacity(); 19918bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy } 1992519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 19935f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setSolidColors(@Nullable ColorStateList colors) { 1994e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientColors = null; 1995e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mSolidColors = colors; 1996e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy computeOpacity(); 1997e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 1998e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 1999e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy private void computeOpacity() { 2000c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverBounds = false; 2001c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverShape = false; 200239824f685c33f8aabbe9526b4cc79b7411e8b37fRaph Levien 2003e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (mGradientColors != null) { 2004e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette for (int i = 0; i < mGradientColors.length; i++) { 2005e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (!isOpaque(mGradientColors[i])) { 2006e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy return; 2007e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 2008e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 2009e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 2010e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 201122cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase // An unfilled shape is not opaque over bounds or shape 2012e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (mGradientColors == null && mSolidColors == null) { 201322cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase return; 201422cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase } 201522cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase 2016c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik // Colors are opaque, so opaqueOverShape=true, 2017c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverShape = true; 2018c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik // and opaqueOverBounds=true if shape fills bounds 2019c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverBounds = mShape == RECTANGLE 2020c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik && mRadius <= 0 2021c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik && mRadiusArray == null; 2022e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 2023e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 20245f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setStroke(int width, @Nullable ColorStateList colors, float dashWidth, 20255f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette float dashGap) { 2026a211dd28b93473c452d68432c602d5209b01c178Alan Viverette mStrokeWidth = width; 2027e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mStrokeColors = colors; 20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokeDashWidth = dashWidth; 20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokeDashGap = dashGap; 2030e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy computeOpacity(); 20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setCornerRadius(float radius) { 20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (radius < 0) { 20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radius = 0; 20369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadius = radius; 20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadiusArray = null; 20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2040e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setCornerRadii(float[] radii) { 20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadiusArray = radii; 20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (radii == null) { 20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadius = 0; 20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2047e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 20489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setSize(int width, int height) { 20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = width; 20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = height; 20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20535f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setGradientRadius(float gradientRadius, @RadiusType int type) { 20549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientRadius = gradientRadius; 2055b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette mGradientRadiusType = type; 20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette static boolean isOpaque(int color) { 2060888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return ((color >> 24) & 0xff) == 0xff; 2061888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette } 2062888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette 206352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette /** 206452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * Creates a new themed GradientDrawable based on the specified constant state. 206552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * <p> 206652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * The resulting drawable is guaranteed to have a new constant state. 206752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * 206852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * @param state Constant state from which the drawable inherits 206952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette */ 2070ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette private GradientDrawable(@NonNull GradientState state, @Nullable Resources res) { 207117cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette mGradientState = state; 207252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 207345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(res); 20749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 207645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private void updateLocalState(Resources res) { 207745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final GradientState state = mGradientState; 207845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 2079e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mSolidColors != null) { 2080519494e207322581075c8ea884fde9d33bb9209eAlan Viverette final int[] currentState = getState(); 2081e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int stateColor = state.mSolidColors.getColorForState(currentState, 0); 2082519494e207322581075c8ea884fde9d33bb9209eAlan Viverette mFillPaint.setColor(stateColor); 2083e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette } else if (state.mGradientColors == null) { 2084cf8675ee176a375f873792684d38a47f78348dffRomain Guy // If we don't have a solid color and we don't have a gradient, 2085cf8675ee176a375f873792684d38a47f78348dffRomain Guy // the app is stroking the shape, set the color to the default 2086cf8675ee176a375f873792684d38a47f78348dffRomain Guy // value of state.mSolidColor 2087cf8675ee176a375f873792684d38a47f78348dffRomain Guy mFillPaint.setColor(0); 20884d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette } else { 20894d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette // Otherwise, make sure the fill alpha is maxed out. 20904d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette mFillPaint.setColor(Color.BLACK); 20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 209217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 20939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPadding = state.mPadding; 209417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 20959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (state.mStrokeWidth >= 0) { 20966a49ddef62865c1b245ad60a13c334f0ffaf1a5fChris Craik mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 20979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setStyle(Paint.Style.STROKE); 20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setStrokeWidth(state.mStrokeWidth); 209917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 2100e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mStrokeColors != null) { 2101083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette final int[] currentState = getState(); 2102e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int strokeStateColor = state.mStrokeColors.getColorForState( 2103083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette currentState, 0); 2104083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette mStrokePaint.setColor(strokeStateColor); 2105083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette } 21069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (state.mStrokeDashWidth != 0.0f) { 210817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final DashPathEffect e = new DashPathEffect( 21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new float[] { state.mStrokeDashWidth, state.mStrokeDashGap }, 0); 21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setPathEffect(e); 21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21133ad771b384b55bc0b9ee9519f457ea7093bb0b74Alan Viverette 2114daec594370f0e47bf07d0c9c968e3c5dfedf0bb5Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 211545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mGradientIsDirty = true; 211645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 211745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette state.computeOpacity(); 21189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2120