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 /** 478daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * Sets the position of the center of the gradient as a fraction of the 479daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * width and height. 480daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <p> 481daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * The default value is (0.5, 0.5). 48241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 48341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <strong>Note</strong>: changing this property will affect all instances 4848bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 48541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing this property. 4868bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 487daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * @param x the X-position of the center of the gradient 488daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * @param y the Y-position of the center of the gradient 4898bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 4908bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 4918bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #setGradientType(int) 49241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getGradientCenterX() 49341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getGradientCenterY() 4948bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGradientCenter(float x, float y) { 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.setGradientCenter(x, y); 4973aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 4989891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5018bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 502daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * Returns the X-position of the center of the gradient as a fraction of 503daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * the width. 50441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 505daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * @return the X-position of the center of the gradient 50641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setGradientCenter(float, float) 50741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 50841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette public float getGradientCenterX() { 50941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette return mGradientState.mCenterX; 51041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 51141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 51241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 513daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * Returns the Y-position of the center of this gradient as a fraction of 514daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * the height. 51541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 516daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * @return the Y-position of the center of the gradient 51741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setGradientCenter(float, float) 51841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 51941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette public float getGradientCenterY() { 52041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette return mGradientState.mCenterY; 52141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 52241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 52341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 52441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Sets the radius of the gradient. The radius is honored only when the 52541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * gradient type is set to {@link #RADIAL_GRADIENT}. 52641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 52741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <strong>Note</strong>: changing this property will affect all instances 5288bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 52941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing this property. 5308bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 53141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @param gradientRadius the radius of the gradient in pixels 5328bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 5338bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 53417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setGradientType(int) 53541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getGradientRadius() 5368bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGradientRadius(float gradientRadius) { 538861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette mGradientState.setGradientRadius(gradientRadius, TypedValue.COMPLEX_UNIT_PX); 5393aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 5409891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5438bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 544861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette * Returns the radius of the gradient in pixels. The radius is valid only 545861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette * when the gradient type is set to {@link #RADIAL_GRADIENT}. 546861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette * 54741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return the radius of the gradient in pixels 54841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setGradientRadius(float) 549861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette */ 550861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette public float getGradientRadius() { 551861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette if (mGradientState.mGradient != RADIAL_GRADIENT) { 552861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette return 0; 553861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette } 554861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette 555861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette ensureValidRect(); 556861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette return mGradientRadius; 557861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette } 558861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette 559861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette /** 560daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * Sets whether this drawable's {@code level} property will be used to 561daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * scale the gradient. If a gradient is not used, this property has no 562daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * effect. 56341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 564daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * Scaling behavior varies based on gradient type: 565daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <ul> 566daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <li>{@link #LINEAR_GRADIENT} adjusts the ending position along the 567daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * gradient's axis of orientation (see {@link #getOrientation()}) 568daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <li>{@link #RADIAL_GRADIENT} adjusts the outer radius 569daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <li>{@link #SWEEP_GRADIENT} adjusts the ending angle 570daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <ul> 571daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <p> 572daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * The default value for this property is {@code false}. 573daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <p> 574daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <strong>Note</strong>: This property corresponds to the 575daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * {@code android:useLevel} attribute on the inner {@code <gradient>} 576daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * tag, NOT the {@code android:useLevel} attribute on the outer 577daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * {@code <shape>} tag. For example, 578daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <pre>{@code 579daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <shape ...> 580daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <gradient 581daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * ... 582daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * android:useLevel="true" /> 583daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * </shape> 584daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * }</pre><p> 585daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * <strong>Note</strong>: Changing this property will affect all instances 5868bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 58741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing this property. 5888bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 589daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * @param useLevel {@code true} if the gradient should be scaled based on 590daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * level, {@code false} otherwise 5918bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 5928bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 5930b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette * @see #setLevel(int) 5940b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette * @see #getLevel() 5955f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette * @see #getUseLevel() 596daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * @attr ref android.R.styleable#GradientDrawableGradient_useLevel 5978bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setUseLevel(boolean useLevel) { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientState.mUseLevel = useLevel; 6003aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 6019891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 60317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 60441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 605daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * Returns whether this drawable's {@code level} property will be used to 606daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * scale the gradient. 60741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 608daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * @return {@code true} if the gradient should be scaled based on level, 60941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@code false} otherwise 61041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setUseLevel(boolean) 611daec5506c45ff0677678fde0732b199cb071250dAlan Viverette * @attr ref android.R.styleable#GradientDrawableGradient_useLevel 61241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 6135f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public boolean getUseLevel() { 61441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette return mGradientState.mUseLevel; 61541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 61641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int modulateAlpha(int alpha) { 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int scale = mAlpha + (mAlpha >> 7); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return alpha * scale >> 8; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6228bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 6238bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * Returns the orientation of the gradient defined in this drawable. 62441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 62541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return the orientation of the gradient defined in this drawable 62641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setOrientation(Orientation) 6278bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 6288bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy public Orientation getOrientation() { 6298bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy return mGradientState.mOrientation; 6308bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy } 6318bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 6328bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 63341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Sets the orientation of the gradient defined in this drawable. 63441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 63541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <strong>Note</strong>: changing orientation will affect all instances 6368bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * of a drawable loaded from a resource. It is recommended to invoke 63741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing the orientation. 63817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * 63941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @param orientation the desired orientation (angle) of the gradient 64017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * 64117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #mutate() 64241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getOrientation() 6438bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 6448bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy public void setOrientation(Orientation orientation) { 6458bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy mGradientState.mOrientation = orientation; 6463aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 6478bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy invalidateSelf(); 6488bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy } 6498bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 6508bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 651e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * Sets the colors used to draw the gradient. 652e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * <p> 653e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * Each color is specified as an ARGB integer and the array must contain at 654e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * least 2 colors. 655e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * <p> 656e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * <strong>Note</strong>: changing colors will affect all instances of a 657e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * drawable loaded from a resource. It is recommended to invoke 658e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * {@link #mutate()} before changing the colors. 6598bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 660e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette * @param colors an array containing 2 or more ARGB colors 6618bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 66217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setColor(int) 6638bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 66480756e38882720860db52f1fcc21fa1505a02abfTor Norbye public void setColors(@ColorInt int[] colors) { 665e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientState.setGradientColors(colors); 6663aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 6678bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy invalidateSelf(); 6688bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy } 6698bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 67041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 67141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Returns the colors used to draw the gradient, or {@code null} if the 67241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * gradient is drawn using a single color or no colors. 67341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 67441551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return the colors used to draw the gradient, or {@code null} 67541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setColors(int[] colors) 67641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 67741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette @Nullable 67841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette public int[] getColors() { 6795f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette return mGradientState.mGradientColors == null ? 6805f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette null : mGradientState.mGradientColors.clone(); 68141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 68241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 68416f1d81d47beb1e04504a76de66e2919dde08c33Alan Viverette public void draw(Canvas canvas) { 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!ensureValidRect()) { 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // nothing to draw 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remember the alpha values, in case we temporarily overwrite them 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when we modulate them with mAlpha 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int prevFillAlpha = mFillPaint.getAlpha(); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int prevStrokeAlpha = mStrokePaint != null ? mStrokePaint.getAlpha() : 0; 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the modulate alpha values 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int currFillAlpha = modulateAlpha(prevFillAlpha); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int currStrokeAlpha = modulateAlpha(prevStrokeAlpha); 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 698e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint != null && 699e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy mStrokePaint.getStrokeWidth() > 0; 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean haveFill = currFillAlpha > 0; 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final GradientState st = mGradientState; 70243027b7bca554818cc4223389747d661819d5706Alan Viverette final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mTintFilter; 70343027b7bca554818cc4223389747d661819d5706Alan Viverette 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* we need a layer iff we're drawing both a fill and stroke, and the 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stroke is non-opaque, and our shapetype actually supports 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fill+stroke. Otherwise we can just draw the stroke (if any) on top 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project of the fill (if any) without worrying about blending artifacts. 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 70943027b7bca554818cc4223389747d661819d5706Alan Viverette final boolean useLayer = haveStroke && haveFill && st.mShape != LINE && 71043027b7bca554818cc4223389747d661819d5706Alan Viverette currStrokeAlpha < 255 && (mAlpha < 255 || colorFilter != null); 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Drawing with a layer is slower than direct drawing, but it 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allows us to apply paint effects like alpha and colorfilter to 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project the result of multiple separate draws. In our case, if the user 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asks for a non-opaque alpha value (via setAlpha), and we're 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stroking, then we need to apply the alpha AFTER we've drawn 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project both the fill and the stroke. 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (useLayer) { 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLayerPaint == null) { 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayerPaint = new Paint(); 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 72307c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mLayerPaint.setDither(st.mDither); 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayerPaint.setAlpha(mAlpha); 72543027b7bca554818cc4223389747d661819d5706Alan Viverette mLayerPaint.setColorFilter(colorFilter); 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float rad = mStrokePaint.getStrokeWidth(); 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.saveLayer(mRect.left - rad, mRect.top - rad, 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRect.right + rad, mRect.bottom + rad, 7301e5d428b3f8cbe2132d6b85f7cc6ad5212a986dcChris Craik mLayerPaint); 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't perform the filter in our individual paints 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // since the layer will do it for us 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setColorFilter(null); 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setColorFilter(null); 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* if we're not using a layer, apply the dither/filter to our 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project individual paints 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setAlpha(currFillAlpha); 74107c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mFillPaint.setDither(st.mDither); 74243027b7bca554818cc4223389747d661819d5706Alan Viverette mFillPaint.setColorFilter(colorFilter); 743e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (colorFilter != null && st.mSolidColors == null) { 744813680780f365648b39873fa26dfae0123d51aedChet Haase mFillPaint.setColor(mAlpha << 24); 74541c769d9a8858ad20b0a6ed942a1cea19ba59d2dRomain Guy } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setAlpha(currStrokeAlpha); 74807c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mStrokePaint.setDither(st.mDither); 74943027b7bca554818cc4223389747d661819d5706Alan Viverette mStrokePaint.setColorFilter(colorFilter); 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 752e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (st.mShape) { 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RECTANGLE: 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st.mRadiusArray != null) { 756e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik buildPathIfDirty(); 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawPath(mPath, mFillPaint); 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawPath(mPath, mStrokePaint); 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 76161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy } else if (st.mRadius > 0.0f) { 7624e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed // since the caller is only giving us 1 value, we will force 7634e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed // it to be square if the rect is too small in one dimension 7644e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed // to show it. If we did nothing, Skia would clamp the rad 76561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy // independently along each axis, giving us a thin ellipse 7664e03999ca20fd326e4ded3d7444ddd5c14f369c7Mike Reed // if the rect were very wide but not very tall 767b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik float rad = Math.min(st.mRadius, 768b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik Math.min(mRect.width(), mRect.height()) * 0.5f); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawRoundRect(mRect, rad, rad, mFillPaint); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawRoundRect(mRect, rad, rad, mStrokePaint); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 77361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy } else { 77443027b7bca554818cc4223389747d661819d5706Alan Viverette if (mFillPaint.getColor() != 0 || colorFilter != null || 775cf8675ee176a375f873792684d38a47f78348dffRomain Guy mFillPaint.getShader() != null) { 776cf8675ee176a375f873792684d38a47f78348dffRomain Guy canvas.drawRect(mRect, mFillPaint); 777cf8675ee176a375f873792684d38a47f78348dffRomain Guy } 77861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy if (haveStroke) { 77961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy canvas.drawRect(mRect, mStrokePaint); 78061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy } 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case OVAL: 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawOval(mRect, mFillPaint); 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawOval(mRect, mStrokePaint); 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LINE: { 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RectF r = mRect; 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = r.centerY(); 79271b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette if (haveStroke) { 79371b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette canvas.drawLine(r.left, y, r.right, y, mStrokePaint); 79471b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette } 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RING: 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Path path = buildRing(st); 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawPath(path, mFillPaint); 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawPath(path, mStrokePaint); 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 80517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (useLayer) { 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.restore(); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setAlpha(prevFillAlpha); 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (haveStroke) { 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setAlpha(prevStrokeAlpha); 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 815e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 816e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik private void buildPathIfDirty() { 817e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik final GradientState st = mGradientState; 8183aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase if (mPathIsDirty) { 8193aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase ensureValidRect(); 820e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik mPath.reset(); 821e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik mPath.addRoundRect(mRect, st.mRadiusArray, Path.Direction.CW); 8223aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mPathIsDirty = false; 823e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik } 824e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik } 825e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Path buildRing(GradientState st) { 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRingPath != null && (!st.mUseLevelForShape || !mPathIsDirty)) return mRingPath; 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPathIsDirty = false; 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8300b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette float sweep = st.mUseLevelForShape ? (360.0f * getLevel() / 10000.0f) : 360f; 83117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RectF bounds = new RectF(mRect); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = bounds.width() / 2.0f; 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = bounds.height() / 2.0f; 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float thickness = st.mThickness != -1 ? 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st.mThickness : bounds.width() / st.mThicknessRatio; 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // inner radius 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float radius = st.mInnerRadius != -1 ? 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st.mInnerRadius : bounds.width() / st.mInnerRadiusRatio; 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RectF innerBounds = new RectF(bounds); 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project innerBounds.inset(x - radius, y - radius); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds = new RectF(innerBounds); 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds.inset(-thickness, -thickness); 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRingPath == null) { 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRingPath = new Path(); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 852b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik mRingPath.reset(); 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Path ringPath = mRingPath; 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // arcTo treats the sweep angle mod 360, so check for that, since we 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // think 360 means draw the entire oval 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sweep < 360 && sweep > -360) { 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.setFillType(Path.FillType.EVEN_ODD); 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // inner top 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.moveTo(x + radius, y); 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // outer top 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.lineTo(x + radius + thickness, y); 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // outer arc 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.arcTo(bounds, 0.0f, sweep, false); 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // inner arc 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.arcTo(innerBounds, sweep, -sweep, false); 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.close(); 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // add the entire ovals 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.addOval(bounds, Path.Direction.CW); 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ringPath.addOval(innerBounds, Path.Direction.CCW); 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ringPath; 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8788bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy /** 87941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Changes this drawable to use a single color instead of a gradient. 88041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <p> 88141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * <strong>Note</strong>: changing color will affect all instances of a 88241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * drawable loaded from a resource. It is recommended to invoke 88341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * {@link #mutate()} before changing the color. 8848bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 8858bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @param argb The color used to fill the shape 8868bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * 8878bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy * @see #mutate() 88817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette * @see #setColors(int[]) 88941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getColor 8908bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy */ 89180756e38882720860db52f1fcc21fa1505a02abfTor Norbye public void setColor(@ColorInt int argb) { 892e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientState.setSolidColors(ColorStateList.valueOf(argb)); 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setColor(argb); 8949891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 897519494e207322581075c8ea884fde9d33bb9209eAlan Viverette /** 898519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * Changes this drawable to use a single color state list instead of a 8997c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette * gradient. Calling this method with a null argument will clear the color 9007c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette * and is equivalent to calling {@link #setColor(int)} with the argument 9017c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette * {@link Color#TRANSPARENT}. 902519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * <p> 903519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * <strong>Note</strong>: changing color will affect all instances of a 904519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * drawable loaded from a resource. It is recommended to invoke 905519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * {@link #mutate()} before changing the color.</p> 906519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * 907519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * @param colorStateList The color state list used to fill the shape 90841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 909519494e207322581075c8ea884fde9d33bb9209eAlan Viverette * @see #mutate() 91041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #getColor 911519494e207322581075c8ea884fde9d33bb9209eAlan Viverette */ 9125f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setColor(@Nullable ColorStateList colorStateList) { 913e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientState.setSolidColors(colorStateList); 91440df78153987409dbf299b84da9784b69029e184Alan Viverette final int color; 9157c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette if (colorStateList == null) { 91640df78153987409dbf299b84da9784b69029e184Alan Viverette color = Color.TRANSPARENT; 9177c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette } else { 91840df78153987409dbf299b84da9784b69029e184Alan Viverette final int[] stateSet = getState(); 91940df78153987409dbf299b84da9784b69029e184Alan Viverette color = colorStateList.getColorForState(stateSet, 0); 9207c263c6ee7433d425aa5f69e7eaeeade027dec2fAlan Viverette } 92140df78153987409dbf299b84da9784b69029e184Alan Viverette mFillPaint.setColor(color); 92240df78153987409dbf299b84da9784b69029e184Alan Viverette invalidateSelf(); 923519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 924519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 92541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette /** 92641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * Returns the color state list used to fill the shape, or {@code null} if 92741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * the shape is filled with a gradient or has no fill color. 92841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 92941551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @return the color state list used to fill this gradient, or {@code null} 93041551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * 93141551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setColor(int) 93241551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette * @see #setColor(ColorStateList) 93341551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette */ 9345f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @Nullable 93541551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette public ColorStateList getColor() { 93641551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette return mGradientState.mSolidColors; 93741551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette } 93841551849e698129d4bd8861a1de9cb58f1300ec5Alan Viverette 939519494e207322581075c8ea884fde9d33bb9209eAlan Viverette @Override 94012b97f5d2b15194ed6673c9838b13c8312157709Alan Viverette protected boolean onStateChange(int[] stateSet) { 941a211dd28b93473c452d68432c602d5209b01c178Alan Viverette boolean invalidateSelf = false; 942a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 943a211dd28b93473c452d68432c602d5209b01c178Alan Viverette final GradientState s = mGradientState; 944e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final ColorStateList solidColors = s.mSolidColors; 945e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (solidColors != null) { 946e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int newColor = solidColors.getColorForState(stateSet, 0); 947519494e207322581075c8ea884fde9d33bb9209eAlan Viverette final int oldColor = mFillPaint.getColor(); 948519494e207322581075c8ea884fde9d33bb9209eAlan Viverette if (oldColor != newColor) { 949519494e207322581075c8ea884fde9d33bb9209eAlan Viverette mFillPaint.setColor(newColor); 950616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette invalidateSelf = true; 951a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 952a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 953a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 954616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette final Paint strokePaint = mStrokePaint; 955616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette if (strokePaint != null) { 956e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final ColorStateList strokeColors = s.mStrokeColors; 957e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (strokeColors != null) { 958e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int newColor = strokeColors.getColorForState(stateSet, 0); 959e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int oldColor = strokePaint.getColor(); 960e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (oldColor != newColor) { 961e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette strokePaint.setColor(newColor); 962616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette invalidateSelf = true; 963616dd4780fb515c596f2764f7e35a30401f7b063Alan Viverette } 964519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 965519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 966519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 96743027b7bca554818cc4223389747d661819d5706Alan Viverette if (s.mTint != null && s.mTintMode != null) { 96843027b7bca554818cc4223389747d661819d5706Alan Viverette mTintFilter = updateTintFilter(mTintFilter, s.mTint, s.mTintMode); 96943027b7bca554818cc4223389747d661819d5706Alan Viverette invalidateSelf = true; 97043027b7bca554818cc4223389747d661819d5706Alan Viverette } 97143027b7bca554818cc4223389747d661819d5706Alan Viverette 972a211dd28b93473c452d68432c602d5209b01c178Alan Viverette if (invalidateSelf) { 973a211dd28b93473c452d68432c602d5209b01c178Alan Viverette invalidateSelf(); 974a211dd28b93473c452d68432c602d5209b01c178Alan Viverette return true; 975a211dd28b93473c452d68432c602d5209b01c178Alan Viverette } 976a211dd28b93473c452d68432c602d5209b01c178Alan Viverette 977a211dd28b93473c452d68432c602d5209b01c178Alan Viverette return false; 978519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 979519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 980519494e207322581075c8ea884fde9d33bb9209eAlan Viverette @Override 981519494e207322581075c8ea884fde9d33bb9209eAlan Viverette public boolean isStateful() { 982a211dd28b93473c452d68432c602d5209b01c178Alan Viverette final GradientState s = mGradientState; 983a211dd28b93473c452d68432c602d5209b01c178Alan Viverette return super.isStateful() 984e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette || (s.mSolidColors != null && s.mSolidColors.isStateful()) 985e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette || (s.mStrokeColors != null && s.mStrokeColors.isStateful()) 98643027b7bca554818cc4223389747d661819d5706Alan Viverette || (s.mTint != null && s.mTint.isStateful()); 987519494e207322581075c8ea884fde9d33bb9209eAlan Viverette } 988519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 990ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette public @Config int getChangingConfigurations() { 991e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return super.getChangingConfigurations() | mGradientState.getChangingConfigurations(); 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9938bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlpha(int alpha) { 9969891e1fce5f29d0421d34aa481037417bd70853dChet Haase if (alpha != mAlpha) { 9979891e1fce5f29d0421d34aa481037417bd70853dChet Haase mAlpha = alpha; 9989891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 9999891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1003b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase public int getAlpha() { 1004b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase return mAlpha; 1005b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase } 1006b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase 1007b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase @Override 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDither(boolean dither) { 100907c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette if (dither != mGradientState.mDither) { 101007c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette mGradientState.mDither = dither; 10119891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 10129891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10165f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @Nullable 101738b5f597de96cd892add9017dc810212f549bf68John Spurlock public ColorFilter getColorFilter() { 101838b5f597de96cd892add9017dc810212f549bf68John Spurlock return mColorFilter; 101938b5f597de96cd892add9017dc810212f549bf68John Spurlock } 102038b5f597de96cd892add9017dc810212f549bf68John Spurlock 102138b5f597de96cd892add9017dc810212f549bf68John Spurlock @Override 10225f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setColorFilter(@Nullable ColorFilter colorFilter) { 1023bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik if (colorFilter != mColorFilter) { 1024bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik mColorFilter = colorFilter; 10259891e1fce5f29d0421d34aa481037417bd70853dChet Haase invalidateSelf(); 10269891e1fce5f29d0421d34aa481037417bd70853dChet Haase } 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10305f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setTintList(@Nullable ColorStateList tint) { 103143027b7bca554818cc4223389747d661819d5706Alan Viverette mGradientState.mTint = tint; 103243027b7bca554818cc4223389747d661819d5706Alan Viverette mTintFilter = updateTintFilter(mTintFilter, tint, mGradientState.mTintMode); 103343027b7bca554818cc4223389747d661819d5706Alan Viverette invalidateSelf(); 103443027b7bca554818cc4223389747d661819d5706Alan Viverette } 103543027b7bca554818cc4223389747d661819d5706Alan Viverette 103643027b7bca554818cc4223389747d661819d5706Alan Viverette @Override 10375f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setTintMode(@Nullable PorterDuff.Mode tintMode) { 103843027b7bca554818cc4223389747d661819d5706Alan Viverette mGradientState.mTintMode = tintMode; 103943027b7bca554818cc4223389747d661819d5706Alan Viverette mTintFilter = updateTintFilter(mTintFilter, mGradientState.mTint, tintMode); 104043027b7bca554818cc4223389747d661819d5706Alan Viverette invalidateSelf(); 104143027b7bca554818cc4223389747d661819d5706Alan Viverette } 104243027b7bca554818cc4223389747d661819d5706Alan Viverette 104343027b7bca554818cc4223389747d661819d5706Alan Viverette @Override 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 1045888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return (mAlpha == 255 && mGradientState.mOpaqueOverBounds && isOpaqueForState()) ? 10460a1c6f021be032f5aecb341c2794efb06c0a8a0dAlan Viverette PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT; 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onBoundsChange(Rect r) { 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onBoundsChange(r); 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRingPath = null; 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPathIsDirty = true; 10543aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10580b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette protected boolean onLevelChange(int level) { 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onLevelChange(level); 10603aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = true; 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPathIsDirty = true; 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidateSelf(); 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10673aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase * This checks mGradientIsDirty, and if it is true, recomputes both our drawing 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rectangle (mRect) and the gradient itself, since it depends on our 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rectangle too. 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the resulting rectangle is not empty, false otherwise 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean ensureValidRect() { 10733aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase if (mGradientIsDirty) { 10743aff2a0813ad77fd41b39b6a636faf2de6d78accChet Haase mGradientIsDirty = false; 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect bounds = getBounds(); 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float inset = 0; 107817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStrokePaint != null) { 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inset = mStrokePaint.getStrokeWidth() * 0.5f; 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final GradientState st = mGradientState; 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRect.set(bounds.left + inset, bounds.top + inset, 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bounds.right - inset, bounds.bottom - inset); 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1088e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int[] gradientColors = st.mGradientColors; 1089e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (gradientColors != null) { 1090e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final RectF r = mRect; 1091e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final float x0, x1, y0, y1; 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st.mGradient == LINEAR_GRADIENT) { 10940b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette final float level = st.mUseLevel ? getLevel() / 10000.0f : 1.0f; 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (st.mOrientation) { 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case TOP_BOTTOM: 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.top; 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = x0; y1 = level * r.bottom; 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case TR_BL: 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.right; y0 = r.top; 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.left; y1 = level * r.bottom; 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case RIGHT_LEFT: 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.right; y0 = r.top; 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.left; y1 = y0; 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case BR_TL: 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.right; y0 = r.bottom; 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.left; y1 = level * r.top; 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case BOTTOM_TOP: 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.bottom; 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = x0; y1 = level * r.top; 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case BL_TR: 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.bottom; 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.right; y1 = level * r.top; 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LEFT_RIGHT: 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.top; 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.right; y1 = y0; 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default:/* TL_BR */ 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left; y0 = r.top; 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x1 = level * r.right; y1 = level * r.bottom; 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setShader(new LinearGradient(x0, y0, x1, y1, 1131e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette gradientColors, st.mPositions, Shader.TileMode.CLAMP)); 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (st.mGradient == RADIAL_GRADIENT) { 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left + (r.right - r.left) * st.mCenterX; 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y0 = r.top + (r.bottom - r.top) * st.mCenterY; 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1136861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette float radius = st.mGradientRadius; 1137b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION) { 1138b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette // Fall back to parent width or height if intrinsic 1139b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette // size is not specified. 1140b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette final float width = st.mWidth >= 0 ? st.mWidth : r.width(); 1141b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette final float height = st.mHeight >= 0 ? st.mHeight : r.height(); 1142b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette radius *= Math.min(width, height); 1143b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette } else if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION_PARENT) { 1144861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette radius *= Math.min(r.width(), r.height()); 1145861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette } 1146b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 1147861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette if (st.mUseLevel) { 11480b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette radius *= getLevel() / 10000.0f; 1149861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette } 1150b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 1151861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette mGradientRadius = radius; 1152b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 1153b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette if (radius <= 0) { 1154b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette // We can't have a shader with non-positive radius, so 1155b4f8a981769e95500ab6c86ab45102dc9c7e53c6Alan Viverette // let's have a very, very small radius. 1156b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette radius = 0.001f; 1157b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette } 1158b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette 1159861621eb8a3bd8896bc00c4c5bc8af6816215e21Alan Viverette mFillPaint.setShader(new RadialGradient( 1160e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette x0, y0, radius, gradientColors, null, Shader.TileMode.CLAMP)); 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (st.mGradient == SWEEP_GRADIENT) { 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x0 = r.left + (r.right - r.left) * st.mCenterX; 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y0 = r.top + (r.bottom - r.top) * st.mCenterY; 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1165e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette int[] tempColors = gradientColors; 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] tempPositions = null; 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (st.mUseLevel) { 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempColors = st.mTempColors; 1170e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int length = gradientColors.length; 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tempColors == null || tempColors.length != length + 1) { 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempColors = st.mTempColors = new int[length + 1]; 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1174e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette System.arraycopy(gradientColors, 0, tempColors, 0, length); 1175e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette tempColors[length] = gradientColors[length - 1]; 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempPositions = st.mTempPositions; 117852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float fraction = 1.0f / (length - 1); 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tempPositions == null || tempPositions.length != length + 1) { 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempPositions = st.mTempPositions = new float[length + 1]; 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11830b6cfe22fda3396b4790ac79fc90488bec4a49a4Alan Viverette final float level = getLevel() / 10000.0f; 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < length; i++) { 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempPositions[i] = i * fraction * level; 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tempPositions[length] = 1.0f; 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFillPaint.setShader(new SweepGradient(x0, y0, tempColors, tempPositions)); 11914d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette } 11924d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette 11934d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette // If we don't have a solid color, the alpha channel must be 11944d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette // maxed out so that alpha modulation works correctly. 1195e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (st.mSolidColors == null) { 11964d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette mFillPaint.setColor(Color.BLACK); 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return !mRect.isEmpty(); 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1204ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette public void inflate(@NonNull Resources r, @NonNull XmlPullParser parser, 1205ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette @NonNull AttributeSet attrs, @Nullable Theme theme) 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 1207ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette super.inflate(r, parser, attrs, theme); 1208ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 1209ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientState.setDensity(Drawable.resolveDensity(r, 0)); 1210ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 121152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawable); 121217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateStateFromTypedArray(a); 121352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 121452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 121552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette inflateChildElements(r, parser, attrs, theme); 121652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 121745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(r); 121852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 121952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 122052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 1221ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette public void applyTheme(@NonNull Theme t) { 122252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette super.applyTheme(t); 122352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 122452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final GradientState state = mGradientState; 122517cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette if (state == null) { 122617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette return; 122752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 122852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 1229ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette state.setDensity(Drawable.resolveDensity(t.getResources(), 0)); 1230ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 123117cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette if (state.mThemeAttrs != null) { 123217cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette final TypedArray a = t.resolveAttributes( 123317cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette state.mThemeAttrs, R.styleable.GradientDrawable); 123417cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette updateStateFromTypedArray(a); 123517cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette a.recycle(); 123617cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette } 123752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 123845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette if (state.mTint != null && state.mTint.canApplyTheme()) { 1239e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette state.mTint = state.mTint.obtainForTheme(t); 124045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 124145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 1242e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mSolidColors != null && state.mSolidColors.canApplyTheme()) { 1243e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette state.mSolidColors = state.mSolidColors.obtainForTheme(t); 124445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 124545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 1246e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mStrokeColors != null && state.mStrokeColors.canApplyTheme()) { 1247e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette state.mStrokeColors = state.mStrokeColors.obtainForTheme(t); 124845c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette } 124945c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 125017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette applyThemeChildElements(t); 125152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 125245c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(t.getResources()); 125352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 125452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 125552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette /** 125652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * Updates the constant state from the values in the typed array. 125752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette */ 125852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private void updateStateFromTypedArray(TypedArray a) { 125952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final GradientState state = mGradientState; 126052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 12618e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 12628e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette state.mChangingConfigurations |= a.getChangingConfigurations(); 12638e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 126417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // Extract the theme attributes, if any. 126517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mThemeAttrs = a.extractThemeAttrs(); 126652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 126717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mShape = a.getInt(R.styleable.GradientDrawable_shape, state.mShape); 126807c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette state.mDither = a.getBoolean(R.styleable.GradientDrawable_dither, state.mDither); 126952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 127052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (state.mShape == RING) { 127117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mInnerRadius = a.getDimensionPixelSize( 127217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_innerRadius, state.mInnerRadius); 127352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 127417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (state.mInnerRadius == -1) { 127552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette state.mInnerRadiusRatio = a.getFloat( 127617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_innerRadiusRatio, state.mInnerRadiusRatio); 127752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 127852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 127917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mThickness = a.getDimensionPixelSize( 128017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_thickness, state.mThickness); 128152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 128217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (state.mThickness == -1) { 128352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette state.mThicknessRatio = a.getFloat( 128417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_thicknessRatio, state.mThicknessRatio); 128552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 128652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 128717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette state.mUseLevelForShape = a.getBoolean( 128817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawable_useLevel, state.mUseLevelForShape); 128952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 129043027b7bca554818cc4223389747d661819d5706Alan Viverette 129143027b7bca554818cc4223389747d661819d5706Alan Viverette final int tintMode = a.getInt(R.styleable.GradientDrawable_tintMode, -1); 129243027b7bca554818cc4223389747d661819d5706Alan Viverette if (tintMode != -1) { 129343027b7bca554818cc4223389747d661819d5706Alan Viverette state.mTintMode = Drawable.parseTintMode(tintMode, PorterDuff.Mode.SRC_IN); 129443027b7bca554818cc4223389747d661819d5706Alan Viverette } 129543027b7bca554818cc4223389747d661819d5706Alan Viverette 129643027b7bca554818cc4223389747d661819d5706Alan Viverette final ColorStateList tint = a.getColorStateList(R.styleable.GradientDrawable_tint); 129743027b7bca554818cc4223389747d661819d5706Alan Viverette if (tint != null) { 129843027b7bca554818cc4223389747d661819d5706Alan Viverette state.mTint = tint; 129943027b7bca554818cc4223389747d661819d5706Alan Viverette } 130087e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette 130187e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette final int insetLeft = a.getDimensionPixelSize( 130287e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette R.styleable.GradientDrawable_opticalInsetLeft, state.mOpticalInsets.left); 130387e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette final int insetTop = a.getDimensionPixelSize( 130487e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette R.styleable.GradientDrawable_opticalInsetTop, state.mOpticalInsets.top); 130587e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette final int insetRight = a.getDimensionPixelSize( 130687e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette R.styleable.GradientDrawable_opticalInsetRight, state.mOpticalInsets.right); 130787e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette final int insetBottom = a.getDimensionPixelSize( 130887e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette R.styleable.GradientDrawable_opticalInsetBottom, state.mOpticalInsets.bottom); 130987e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette state.mOpticalInsets = Insets.of(insetLeft, insetTop, insetRight, insetBottom); 131052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 131152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 131252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 131352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public boolean canApplyTheme() { 1314d21fd9d1ccd2b525f9c004a6cd9ba19a645701abAlan Viverette return (mGradientState != null && mGradientState.canApplyTheme()) || super.canApplyTheme(); 131552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 131652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 131752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private void applyThemeChildElements(Theme t) { 131817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 131952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 132017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrSize != null) { 132117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 132217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrSize, R.styleable.GradientDrawableSize); 132317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableSize(a); 132452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 132552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 132652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 132717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrGradient != null) { 132817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 132917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrGradient, R.styleable.GradientDrawableGradient); 133017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette try { 133117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableGradient(t.getResources(), a); 133217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } catch (XmlPullParserException e) { 1333c078c605ab904b0e4a5d793cbeffd78c340f2816Alan Viverette rethrowAsRuntimeException(e); 133417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } finally { 133517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a.recycle(); 133617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } 133752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 133852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 133917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrSolid != null) { 134017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 134117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrSolid, R.styleable.GradientDrawableSolid); 134217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableSolid(a); 134352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 134452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 134552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 134617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrStroke != null) { 134717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 134817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrStroke, R.styleable.GradientDrawableStroke); 134917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableStroke(a); 135052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 135152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 135252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 135317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrCorners != null) { 135417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 135517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrCorners, R.styleable.DrawableCorners); 135617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateDrawableCorners(a); 135752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 135852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 135952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 136017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (st.mAttrPadding != null) { 136117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedArray a = t.resolveAttributes( 136217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrPadding, R.styleable.GradientDrawablePadding); 136317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawablePadding(a); 136452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.recycle(); 136552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 136652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 136752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 136852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs, 136952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette Theme theme) throws XmlPullParserException, IOException { 137052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette TypedArray a; 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int type; 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1373ed7894352f8addfe3d0da75cc7fe8bc6fef201dcRomain Guy final int innerDepth = parser.getDepth() + 1; 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int depth; 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && ((depth=parser.getDepth()) >= innerDepth 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || type != XmlPullParser.END_TAG)) { 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != XmlPullParser.START_TAG) { 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (depth > innerDepth) { 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 138552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = parser.getName(); 138717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name.equals("size")) { 138917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableSize); 139017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableSize(a); 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("gradient")) { 139317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableGradient); 139417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableGradient(r, a); 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("solid")) { 139717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableSolid); 139817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableSolid(a); 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("stroke")) { 140117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawableStroke); 140217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawableStroke(a); 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("corners")) { 140517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.DrawableCorners); 140617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateDrawableCorners(a); 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (name.equals("padding")) { 140917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a = obtainAttributes(r, theme, attrs, R.styleable.GradientDrawablePadding); 141017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette updateGradientDrawablePadding(a); 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w("drawable", "Bad element under <shape>: " + name); 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 141552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 141652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 141752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 141817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawablePadding(TypedArray a) { 141917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 142052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 14218e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 14228e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 14238e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 142452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // Extract the theme attributes, if any. 142517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrPadding = a.extractThemeAttrs(); 142617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1427982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette if (st.mPadding == null) { 1428982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette st.mPadding = new Rect(); 1429982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette } 1430982c59a55f8f11d0e26be93780b292adacd56f49Alan Viverette 143117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final Rect pad = st.mPadding; 143217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette pad.set(a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_left, pad.left), 143317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_top, pad.top), 143417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_right, pad.right), 143517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a.getDimensionPixelOffset(R.styleable.GradientDrawablePadding_bottom, pad.bottom)); 143617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette mPadding = pad; 143752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 1438e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 143917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateDrawableCorners(TypedArray a) { 144017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 144117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 14428e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 14438e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 14448e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 144517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // Extract the theme attributes, if any. 144617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrCorners = a.extractThemeAttrs(); 144717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 144817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int radius = a.getDimensionPixelSize( 144917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.DrawableCorners_radius, (int) st.mRadius); 145052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setCornerRadius(radius); 145117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 145217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // TODO: Update these to be themeable. 145317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int topLeftRadius = a.getDimensionPixelSize( 145452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.DrawableCorners_topLeftRadius, radius); 145517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int topRightRadius = a.getDimensionPixelSize( 145652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.DrawableCorners_topRightRadius, radius); 145717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int bottomLeftRadius = a.getDimensionPixelSize( 145852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.DrawableCorners_bottomLeftRadius, radius); 145917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final int bottomRightRadius = a.getDimensionPixelSize( 146052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.DrawableCorners_bottomRightRadius, radius); 146152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (topLeftRadius != radius || topRightRadius != radius || 146252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette bottomLeftRadius != radius || bottomRightRadius != radius) { 146352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // The corner radii are specified in clockwise order (see Path.addRoundRect()) 146452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setCornerRadii(new float[] { 146552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette topLeftRadius, topLeftRadius, 146652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette topRightRadius, topRightRadius, 146752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette bottomRightRadius, bottomRightRadius, 146852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette bottomLeftRadius, bottomLeftRadius 146952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette }); 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 147152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 147252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 147317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawableStroke(TypedArray a) { 147417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 147517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 14768e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 14778e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 14788e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 14798e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Extract the theme attributes, if any. 148017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrStroke = a.extractThemeAttrs(); 148117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 14823b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette // We have an explicit stroke defined, so the default stroke width 14833b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette // must be at least 0 or the current stroke width. 14843b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final int defaultStrokeWidth = Math.max(0, st.mStrokeWidth); 148552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int width = a.getDimensionPixelSize( 14863b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette R.styleable.GradientDrawableStroke_width, defaultStrokeWidth); 148752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float dashWidth = a.getDimension( 148817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableStroke_dashWidth, st.mStrokeDashWidth); 148917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 149017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette ColorStateList colorStateList = a.getColorStateList( 149117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableStroke_color); 149217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (colorStateList == null) { 1493e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette colorStateList = st.mStrokeColors; 149417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } 149517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 149652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (dashWidth != 0.0f) { 149752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float dashGap = a.getDimension( 149817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableStroke_dashGap, st.mStrokeDashGap); 149952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setStroke(width, colorStateList, dashWidth, dashGap); 150052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 150152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette setStroke(width, colorStateList); 150252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 150352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 150452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 150517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawableSolid(TypedArray a) { 15068e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette final GradientState st = mGradientState; 15078e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 15088e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 15098e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 15108e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 15118e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Extract the theme attributes, if any. 15128e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mAttrSolid = a.extractThemeAttrs(); 151317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 151452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final ColorStateList colorStateList = a.getColorStateList( 151552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableSolid_color); 151617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette if (colorStateList != null) { 151717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette setColor(colorStateList); 151817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette } 151952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 152052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 152117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawableGradient(Resources r, TypedArray a) 152252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette throws XmlPullParserException { 152352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final GradientState st = mGradientState; 152417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 15258e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 15268e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 15278e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 152817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // Extract the theme attributes, if any. 152917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrGradient = a.extractThemeAttrs(); 153017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 153117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mCenterX = getFloatOrFraction( 153217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a, R.styleable.GradientDrawableGradient_centerX, st.mCenterX); 153317dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mCenterY = getFloatOrFraction( 153417dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette a, R.styleable.GradientDrawableGradient_centerY, st.mCenterY); 153517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mUseLevel = a.getBoolean( 153617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableGradient_useLevel, st.mUseLevel); 153717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mGradient = a.getInt( 153817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette R.styleable.GradientDrawableGradient_type, st.mGradient); 153917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 154017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette // TODO: Update these to be themeable. 154152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int startColor = a.getColor( 154252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableGradient_startColor, 0); 154352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final boolean hasCenterColor = a.hasValue( 154452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableGradient_centerColor); 154552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int centerColor = a.getColor( 154652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableGradient_centerColor, 0); 154752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int endColor = a.getColor( 154852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette R.styleable.GradientDrawableGradient_endColor, 0); 154952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 155052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (hasCenterColor) { 1551e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors = new int[3]; 1552e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[0] = startColor; 1553e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[1] = centerColor; 1554e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[2] = endColor; 155517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 155652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mPositions = new float[3]; 155752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mPositions[0] = 0.0f; 155852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // Since 0.5f is default value, try to take the one that isn't 0.5f 155952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mPositions[1] = st.mCenterX != 0.5f ? st.mCenterX : st.mCenterY; 156052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mPositions[2] = 1f; 156152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 1562e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors = new int[2]; 1563e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[0] = startColor; 1564e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette st.mGradientColors[1] = endColor; 156552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 156652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 156752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (st.mGradient == LINEAR_GRADIENT) { 156817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle); 156952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette angle %= 360; 157052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 157152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (angle % 45 != 0) { 157252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette throw new XmlPullParserException(a.getPositionDescription() 157352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette + "<gradient> tag requires 'angle' attribute to " 157452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette + "be a multiple of 45"); 157552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 157652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 157717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAngle = angle; 157817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 157952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette switch (angle) { 158052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 0: 158152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.LEFT_RIGHT; 158252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 158352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 45: 158452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.BL_TR; 158552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 158652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 90: 158752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.BOTTOM_TOP; 158852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 158952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 135: 159052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.BR_TL; 159152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 159252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 180: 159352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.RIGHT_LEFT; 159452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 159552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 225: 159652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.TR_BL; 159752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 159852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 270: 159952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.TOP_BOTTOM; 160052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 160152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette case 315: 160252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mOrientation = Orientation.TL_BR; 160352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette break; 160452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 160552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 160617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius); 160752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (tv != null) { 160852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final float radius; 16095f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette final @RadiusType int radiusType; 161052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (tv.type == TypedValue.TYPE_FRACTION) { 161152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radius = tv.getFraction(1.0f, 1.0f); 161252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 161352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT) 161452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette & TypedValue.COMPLEX_UNIT_MASK; 161552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) { 161652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radiusType = RADIUS_TYPE_FRACTION_PARENT; 161752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else { 161852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radiusType = RADIUS_TYPE_FRACTION; 161952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 16202efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette } else if (tv.type == TypedValue.TYPE_DIMENSION) { 162152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radius = tv.getDimension(r.getDisplayMetrics()); 162252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette radiusType = RADIUS_TYPE_PIXELS; 16232efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette } else { 16242efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette radius = tv.getFloat(); 16252efbe9816e097a07864a04f0722d5669b98699f4Alan Viverette radiusType = RADIUS_TYPE_PIXELS; 162652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 162752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 162852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mGradientRadius = radius; 162952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette st.mGradientRadiusType = radiusType; 163052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } else if (st.mGradient == RADIAL_GRADIENT) { 163152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette throw new XmlPullParserException( 163252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette a.getPositionDescription() 163352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette + "<gradient> tag requires 'gradientRadius' " 163452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette + "attribute with radial type"); 163552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 163652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 163752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 163852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 163917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette private void updateGradientDrawableSize(TypedArray a) { 164017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final GradientState st = mGradientState; 164152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 16428e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette // Account for any configuration changes. 16438e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette st.mChangingConfigurations |= a.getChangingConfigurations(); 16448e5e11b99fac942122ee2d6cdd30af51564861aeAlan Viverette 164552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette // Extract the theme attributes, if any. 164617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mAttrSize = a.extractThemeAttrs(); 164717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 164817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mWidth = a.getDimensionPixelSize(R.styleable.GradientDrawableSize_width, st.mWidth); 164917dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette st.mHeight = a.getDimensionPixelSize(R.styleable.GradientDrawableSize_height, st.mHeight); 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static float getFloatOrFraction(TypedArray a, int index, float defaultValue) { 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedValue tv = a.peekValue(index); 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v = defaultValue; 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tv != null) { 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean vIsFraction = tv.type == TypedValue.TYPE_FRACTION; 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v = vIsFraction ? tv.getFraction(1.0f, 1.0f) : tv.getFloat(); 16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return v; 16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 166117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicWidth() { 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mGradientState.mWidth; 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getIntrinsicHeight() { 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mGradientState.mHeight; 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 167117dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 167287e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette /** @hide */ 167387e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette @Override 167487e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette public Insets getOpticalInsets() { 167587e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette return mGradientState.mOpticalInsets; 167687e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette } 167787e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ConstantState getConstantState() { 16806efd2bad954e0e5bd74916a32f036a0f149dcd4dChristopher Lais mGradientState.mChangingConfigurations = getChangingConfigurations(); 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mGradientState; 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1684888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette private boolean isOpaqueForState() { 1685888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette if (mGradientState.mStrokeWidth >= 0 && mStrokePaint != null 1686888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette && !isOpaque(mStrokePaint.getColor())) { 1687888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return false; 1688888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette } 1689888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette 16905f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette // Don't check opacity if we're using a gradient, as we've already 16915f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette // checked the gradient opacity in mOpaqueOverShape. 16925f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette if (mGradientState.mGradientColors == null && !isOpaque(mFillPaint.getColor())) { 1693888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return false; 1694888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette } 1695888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette 1696888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return true; 1697888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette } 1698888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 170031ba192dd201df2cad96a8c503f730130ab0d80fChris Craik public void getOutline(Outline outline) { 1701b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik final GradientState st = mGradientState; 1702b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik final Rect bounds = getBounds(); 1703f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik // only report non-zero alpha if shape being drawn has consistent opacity over shape. Must 1704f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik // either not have a stroke, or have same stroke/fill opacity 1705f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik boolean useFillOpacity = st.mOpaqueOverShape && (mGradientState.mStrokeWidth <= 0 1706f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik || mStrokePaint == null 1707f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik || mStrokePaint.getAlpha() == mFillPaint.getAlpha()); 1708f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik outline.setAlpha(useFillOpacity 1709f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik ? modulateAlpha(mFillPaint.getAlpha()) / 255.0f 1710f3dc7ac7242046d70e4ffee41fd7dbc9b9674ec0Chris Craik : 0.0f); 1711b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik 1712b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik switch (st.mShape) { 1713b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik case RECTANGLE: 1714b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik if (st.mRadiusArray != null) { 1715e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik buildPathIfDirty(); 1716e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik outline.setConvexPath(mPath); 171731ba192dd201df2cad96a8c503f730130ab0d80fChris Craik return; 1718b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik } 1719e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik 1720b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik float rad = 0; 1721b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik if (st.mRadius > 0.0f) { 1722b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik // clamp the radius based on width & height, matching behavior in draw() 1723b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik rad = Math.min(st.mRadius, 1724b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik Math.min(bounds.width(), bounds.height()) * 0.5f); 1725b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik } 17267979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik outline.setRoundRect(bounds, rad); 172731ba192dd201df2cad96a8c503f730130ab0d80fChris Craik return; 17287979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik case OVAL: 17297979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik outline.setOval(bounds); 173031ba192dd201df2cad96a8c503f730130ab0d80fChris Craik return; 17317979388d4f7d5d9dbfcf7e1cc4709f8088c034aeChris Craik case LINE: 17323b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette // Hairlines (0-width stroke) must have a non-empty outline for 17333b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette // shadows to draw correctly, so we'll use a very small width. 17343b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final float halfStrokeWidth = mStrokePaint == null ? 17353b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette 0.0001f : mStrokePaint.getStrokeWidth() * 0.5f; 17363b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final float centerY = bounds.centerY(); 17373b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final int top = (int) Math.floor(centerY - halfStrokeWidth); 17383b983a74c6bac40aad191dfcfbed930cd25a9a01Alan Viverette final int bottom = (int) Math.ceil(centerY + halfStrokeWidth); 1739b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik 1740e6a39b12656ab8d5c77d8366b24aa6410fd42e11Chris Craik outline.setRect(bounds.left, top, bounds.right, bottom); 174131ba192dd201df2cad96a8c503f730130ab0d80fChris Craik return; 1742b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik default: 174331ba192dd201df2cad96a8c503f730130ab0d80fChris Craik // TODO: support more complex shapes 1744b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik } 1745b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik } 1746b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik 1747b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik @Override 17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable mutate() { 17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mMutated && super.mutate() == this) { 1750ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientState = new GradientState(mGradientState, null); 175145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(null); 17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMutated = true; 17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return this; 17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1757727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette /** 1758727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette * @hide 1759727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette */ 1760727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette public void clearMutated() { 1761727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette super.clearMutated(); 1762727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette mMutated = false; 1763727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette } 1764727cae197b123ef764a1f8fbe08a995b000d14c3Alan Viverette 17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final static class GradientState extends ConstantState { 1766ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette public @Config int mChangingConfigurations; 17675f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public @Shape int mShape = RECTANGLE; 17685f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public @GradientType int mGradient = LINEAR_GRADIENT; 176971b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public int mAngle = 0; 17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Orientation mOrientation; 1771e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public ColorStateList mSolidColors; 1772e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public ColorStateList mStrokeColors; 17735f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public @ColorInt int[] mGradientColors; 17745f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public @ColorInt int[] mTempColors; // no need to copy 17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float[] mTempPositions; // no need to copy 17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float[] mPositions; 177771b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public int mStrokeWidth = -1; // if >= 0 use stroking. 177871b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public float mStrokeDashWidth = 0.0f; 177971b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public float mStrokeDashGap = 0.0f; 178071b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public float mRadius = 0.0f; // use this if mRadiusArray is null 178171b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public float[] mRadiusArray = null; 178271b2fbde5601b2347992c4e489d6dfe5f2c777e1Alan Viverette public Rect mPadding = null; 17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mWidth = -1; 17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mHeight = -1; 178517dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public float mInnerRadiusRatio = DEFAULT_INNER_RADIUS_RATIO; 178617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public float mThicknessRatio = DEFAULT_THICKNESS_RATIO; 178717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public int mInnerRadius = -1; 178817dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette public int mThickness = -1; 178907c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette public boolean mDither = false; 179087e1938be8e6c2ac7e6163a63df5dd69633cc836Alan Viverette public Insets mOpticalInsets = Insets.NONE; 179107c661e677b354c2298a2b81f19fd24e5ab1b0e0Alan Viverette 1792969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette float mCenterX = 0.5f; 1793969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette float mCenterY = 0.5f; 1794969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette float mGradientRadius = 0.5f; 17955f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette @RadiusType int mGradientRadiusType = RADIUS_TYPE_PIXELS; 1796969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette boolean mUseLevel = false; 1797969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette boolean mUseLevelForShape = true; 1798969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette 1799969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette boolean mOpaqueOverBounds; 1800969ca91acd008cb33b72888e0b9e7109556db019Alan Viverette boolean mOpaqueOverShape; 18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 180243027b7bca554818cc4223389747d661819d5706Alan Viverette ColorStateList mTint = null; 180343027b7bca554818cc4223389747d661819d5706Alan Viverette PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE; 180443027b7bca554818cc4223389747d661819d5706Alan Viverette 1805ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette int mDensity = DisplayMetrics.DENSITY_DEFAULT; 1806ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 180752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mThemeAttrs; 180852b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrSize; 180952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrGradient; 181052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrSolid; 181152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrStroke; 181252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrCorners; 181352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette int[] mAttrPadding; 181452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 1815e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette public GradientState(Orientation orientation, int[] gradientColors) { 18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOrientation = orientation; 1817e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette setGradientColors(gradientColors); 18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1820ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette public GradientState(@NonNull GradientState orig, @Nullable Resources res) { 1821ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mChangingConfigurations = orig.mChangingConfigurations; 1822ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mShape = orig.mShape; 1823ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradient = orig.mGradient; 1824ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAngle = orig.mAngle; 1825ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOrientation = orig.mOrientation; 1826ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mSolidColors = orig.mSolidColors; 1827ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (orig.mGradientColors != null) { 1828ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientColors = orig.mGradientColors.clone(); 1829562bf17c6c7c5226b2220e27a1543d4a43543d6cPhil Dubach } 1830ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (orig.mPositions != null) { 1831ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPositions = orig.mPositions.clone(); 18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1833ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeColors = orig.mStrokeColors; 1834ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeWidth = orig.mStrokeWidth; 1835ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeDashWidth = orig.mStrokeDashWidth; 1836ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeDashGap = orig.mStrokeDashGap; 1837ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadius = orig.mRadius; 1838ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (orig.mRadiusArray != null) { 1839ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadiusArray = orig.mRadiusArray.clone(); 18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1841ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (orig.mPadding != null) { 1842ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding = new Rect(orig.mPadding); 1843ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1844ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mWidth = orig.mWidth; 1845ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mHeight = orig.mHeight; 1846ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mInnerRadiusRatio = orig.mInnerRadiusRatio; 1847ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mThicknessRatio = orig.mThicknessRatio; 1848ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mInnerRadius = orig.mInnerRadius; 1849ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mThickness = orig.mThickness; 1850ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mDither = orig.mDither; 1851ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpticalInsets = orig.mOpticalInsets; 1852ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mCenterX = orig.mCenterX; 1853ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mCenterY = orig.mCenterY; 1854ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientRadius = orig.mGradientRadius; 1855ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientRadiusType = orig.mGradientRadiusType; 1856ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mUseLevel = orig.mUseLevel; 1857ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mUseLevelForShape = orig.mUseLevelForShape; 1858ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpaqueOverBounds = orig.mOpaqueOverBounds; 1859ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpaqueOverShape = orig.mOpaqueOverShape; 1860ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mTint = orig.mTint; 1861ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mTintMode = orig.mTintMode; 1862ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mThemeAttrs = orig.mThemeAttrs; 1863ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAttrSize = orig.mAttrSize; 1864ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAttrGradient = orig.mAttrGradient; 1865ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAttrSolid = orig.mAttrSolid; 1866ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAttrStroke = orig.mAttrStroke; 1867ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAttrCorners = orig.mAttrCorners; 1868ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mAttrPadding = orig.mAttrPadding; 1869ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 1870ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mDensity = Drawable.resolveDensity(res, orig.mDensity); 1871ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (orig.mDensity != mDensity) { 1872ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette applyDensityScaling(orig.mDensity, mDensity); 1873ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1874ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1875ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 1876ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette /** 1877ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * Sets the constant state density. 1878ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * <p> 1879ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * If the density has been previously set, dispatches the change to 1880ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * subclasses so that density-dependent properties may be scaled as 1881ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * necessary. 1882ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * 1883ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette * @param targetDensity the new constant state density 1884ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette */ 1885ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette public final void setDensity(int targetDensity) { 1886ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mDensity != targetDensity) { 1887ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final int sourceDensity = mDensity; 1888ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mDensity = targetDensity; 1889ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 1890ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette applyDensityScaling(sourceDensity, targetDensity); 1891ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1892ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1893ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 1894ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette private void applyDensityScaling(int sourceDensity, int targetDensity) { 1895ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mInnerRadius > 0) { 1896ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mInnerRadius = Drawable.scaleFromDensity( 1897ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mInnerRadius, sourceDensity, targetDensity, true); 1898ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1899ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mThickness > 0) { 1900ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mThickness = Drawable.scaleFromDensity( 1901ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mThickness, sourceDensity, targetDensity, true); 1902ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1903ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mOpticalInsets != Insets.NONE) { 1904ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final int left = Drawable.scaleFromDensity( 1905ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpticalInsets.left, sourceDensity, targetDensity, true); 1906ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final int top = Drawable.scaleFromDensity( 1907ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpticalInsets.top, sourceDensity, targetDensity, true); 1908ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final int right = Drawable.scaleFromDensity( 1909ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpticalInsets.right, sourceDensity, targetDensity, true); 1910ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final int bottom = Drawable.scaleFromDensity( 1911ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpticalInsets.bottom, sourceDensity, targetDensity, true); 1912ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mOpticalInsets = Insets.of(left, top, right, bottom); 1913ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1914ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mPadding != null) { 1915ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.left = Drawable.scaleFromDensity( 1916ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.left, sourceDensity, targetDensity, false); 1917ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.top = Drawable.scaleFromDensity( 1918ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.top, sourceDensity, targetDensity, false); 1919ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.right = Drawable.scaleFromDensity( 1920ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.right, sourceDensity, targetDensity, false); 1921ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.bottom = Drawable.scaleFromDensity( 1922ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mPadding.bottom, sourceDensity, targetDensity, false); 1923ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1924ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mRadius > 0) { 1925ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadius = Drawable.scaleFromDensity(mRadius, sourceDensity, targetDensity); 1926ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1927ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mRadiusArray != null) { 1928ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadiusArray[0] = Drawable.scaleFromDensity( 1929ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette (int) mRadiusArray[0], sourceDensity, targetDensity, true); 1930ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadiusArray[1] = Drawable.scaleFromDensity( 1931ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette (int) mRadiusArray[1], sourceDensity, targetDensity, true); 1932ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadiusArray[2] = Drawable.scaleFromDensity( 1933ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette (int) mRadiusArray[2], sourceDensity, targetDensity, true); 1934ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mRadiusArray[3] = Drawable.scaleFromDensity( 1935ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette (int) mRadiusArray[3], sourceDensity, targetDensity, true); 1936ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1937ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mStrokeWidth > 0) { 1938ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeWidth = Drawable.scaleFromDensity( 1939ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeWidth, sourceDensity, targetDensity, true); 1940ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1941ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mStrokeDashWidth > 0) { 1942ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeDashWidth = Drawable.scaleFromDensity( 1943ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeDashGap, sourceDensity, targetDensity); 1944ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1945ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mStrokeDashGap > 0) { 1946ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeDashGap = Drawable.scaleFromDensity( 1947ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mStrokeDashGap, sourceDensity, targetDensity); 1948ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1949ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mGradientRadiusType == RADIUS_TYPE_PIXELS) { 1950ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientRadius = Drawable.scaleFromDensity( 1951ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mGradientRadius, sourceDensity, targetDensity); 1952ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1953ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mWidth > 0) { 1954ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mWidth = Drawable.scaleFromDensity(mWidth, sourceDensity, targetDensity, true); 1955ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1956ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (mHeight > 0) { 1957ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette mHeight = Drawable.scaleFromDensity(mHeight, sourceDensity, targetDensity, true); 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 195952b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette } 196052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 196152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette @Override 196252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette public boolean canApplyTheme() { 196345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return mThemeAttrs != null 196445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || mAttrSize != null || mAttrGradient != null 196545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || mAttrSolid != null || mAttrStroke != null 196645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || mAttrCorners != null || mAttrPadding != null 196745c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || (mTint != null && mTint.canApplyTheme()) 1968e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette || (mStrokeColors != null && mStrokeColors.canApplyTheme()) 1969e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette || (mSolidColors != null && mSolidColors.canApplyTheme()) 197045c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette || super.canApplyTheme(); 19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable newDrawable() { 197545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette return new GradientDrawable(this, null); 19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 197717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1979ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette public Drawable newDrawable(@Nullable Resources res) { 1980ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette // If this drawable is being created for a different density, 1981ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette // just create a new constant state and call it a day. 1982ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final GradientState state; 1983ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette final int density = Drawable.resolveDensity(res, mDensity); 1984ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette if (density != mDensity) { 1985ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette state = new GradientState(this, res); 1986ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } else { 1987ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette state = this; 1988ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette } 1989ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette 1990ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette return new GradientDrawable(state, res); 1991c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn } 199217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 1993c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn @Override 1994ac85f90466dd60d2af8ffc3942d503a0de606726Alan Viverette public @Config int getChangingConfigurations() { 1995e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette return mChangingConfigurations 1996e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette | (mStrokeColors != null ? mStrokeColors.getChangingConfigurations() : 0) 1997e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette | (mSolidColors != null ? mSolidColors.getChangingConfigurations() : 0) 1998e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette | (mTint != null ? mTint.getChangingConfigurations() : 0); 19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20015f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setShape(@Shape int shape) { 20029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShape = shape; 2003e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy computeOpacity(); 20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20065f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setGradientType(@GradientType int gradient) { 20079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradient = gradient; 20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGradientCenter(float x, float y) { 20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCenterX = x; 20129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCenterY = y; 20139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20155f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setGradientColors(@Nullable int[] colors) { 2016e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientColors = colors; 2017e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mSolidColors = null; 2018e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy computeOpacity(); 20198bd9698b66d2e1219931ca1be5f81efaba3ed95aRomain Guy } 2020519494e207322581075c8ea884fde9d33bb9209eAlan Viverette 20215f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setSolidColors(@Nullable ColorStateList colors) { 2022e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mGradientColors = null; 2023e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mSolidColors = colors; 2024e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy computeOpacity(); 2025e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 2026e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 2027e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy private void computeOpacity() { 2028c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverBounds = false; 2029c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverShape = false; 203039824f685c33f8aabbe9526b4cc79b7411e8b37fRaph Levien 2031e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (mGradientColors != null) { 2032e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette for (int i = 0; i < mGradientColors.length; i++) { 2033e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (!isOpaque(mGradientColors[i])) { 2034e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy return; 2035e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 2036e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 2037e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 2038e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 203922cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase // An unfilled shape is not opaque over bounds or shape 2040e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (mGradientColors == null && mSolidColors == null) { 204122cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase return; 204222cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase } 204322cf0b0cb856336d36961280b1e968a91d4488d5Chet Haase 2044c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik // Colors are opaque, so opaqueOverShape=true, 2045c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverShape = true; 2046c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik // and opaqueOverBounds=true if shape fills bounds 2047c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik mOpaqueOverBounds = mShape == RECTANGLE 2048c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik && mRadius <= 0 2049c49e3ce6c6ac5100dc5a73c6bd12cbfda4d4ca76Chris Craik && mRadiusArray == null; 2050e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy } 2051e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 20525f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setStroke(int width, @Nullable ColorStateList colors, float dashWidth, 20535f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette float dashGap) { 2054a211dd28b93473c452d68432c602d5209b01c178Alan Viverette mStrokeWidth = width; 2055e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette mStrokeColors = colors; 20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokeDashWidth = dashWidth; 20579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokeDashGap = dashGap; 2058e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy computeOpacity(); 20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setCornerRadius(float radius) { 20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (radius < 0) { 20639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project radius = 0; 20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadius = radius; 20669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadiusArray = null; 20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2068e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setCornerRadii(float[] radii) { 20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadiusArray = radii; 20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (radii == null) { 20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadius = 0; 20739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2075e91aa0fa64db892194ba82ec7d41df6fb9185471Romain Guy 20769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setSize(int width, int height) { 20779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidth = width; 20789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeight = height; 20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20815f63721a6c2c29e639d8d239834a825c535c034aAlan Viverette public void setGradientRadius(float gradientRadius, @RadiusType int type) { 20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGradientRadius = gradientRadius; 2083b32b8a52a3aa2d9d7b5ffaea28e0e31cb077f5e0Alan Viverette mGradientRadiusType = type; 20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2087888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette static boolean isOpaque(int color) { 2088888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette return ((color >> 24) & 0xff) == 0xff; 2089888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette } 2090888b4cf73c9663be37c4faa1249cef1a6a8f8c38Alan Viverette 209152b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette /** 209252b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * Creates a new themed GradientDrawable based on the specified constant state. 209352b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * <p> 209452b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * The resulting drawable is guaranteed to have a new constant state. 209552b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * 209652b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette * @param state Constant state from which the drawable inherits 209752b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette */ 2098ce52037e0ae0c380f5b834fb3dad105bfaf5e374Alan Viverette private GradientDrawable(@NonNull GradientState state, @Nullable Resources res) { 209917cd4dfe3a05c2eddbcbc76066ff3b13fc3f2c8bAlan Viverette mGradientState = state; 210052b999f0721b53e9c6e18a4bd664e89aeb65b2d5Alan Viverette 210145c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette updateLocalState(res); 21029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 210445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette private void updateLocalState(Resources res) { 210545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette final GradientState state = mGradientState; 210645c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 2107e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mSolidColors != null) { 2108519494e207322581075c8ea884fde9d33bb9209eAlan Viverette final int[] currentState = getState(); 2109e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int stateColor = state.mSolidColors.getColorForState(currentState, 0); 2110519494e207322581075c8ea884fde9d33bb9209eAlan Viverette mFillPaint.setColor(stateColor); 2111e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette } else if (state.mGradientColors == null) { 2112cf8675ee176a375f873792684d38a47f78348dffRomain Guy // If we don't have a solid color and we don't have a gradient, 2113cf8675ee176a375f873792684d38a47f78348dffRomain Guy // the app is stroking the shape, set the color to the default 2114cf8675ee176a375f873792684d38a47f78348dffRomain Guy // value of state.mSolidColor 2115cf8675ee176a375f873792684d38a47f78348dffRomain Guy mFillPaint.setColor(0); 21164d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette } else { 21174d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette // Otherwise, make sure the fill alpha is maxed out. 21184d971c1fa0c71400ff1e843b8d8b4826d0aece16Alan Viverette mFillPaint.setColor(Color.BLACK); 21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 212017dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 21219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPadding = state.mPadding; 212217dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 21239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (state.mStrokeWidth >= 0) { 21246a49ddef62865c1b245ad60a13c334f0ffaf1a5fChris Craik mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setStyle(Paint.Style.STROKE); 21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setStrokeWidth(state.mStrokeWidth); 212717dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette 2128e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette if (state.mStrokeColors != null) { 2129083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette final int[] currentState = getState(); 2130e0f95f39c5a669a48ee3ebb8dc45bf2d7ee940f1Alan Viverette final int strokeStateColor = state.mStrokeColors.getColorForState( 2131083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette currentState, 0); 2132083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette mStrokePaint.setColor(strokeStateColor); 2133083f5518d73e15d70ceb5c0cbc1370eda1928252Alan Viverette } 21349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (state.mStrokeDashWidth != 0.0f) { 213617dafdc8d8cb92a03294657d3a6e36c9c546d130Alan Viverette final DashPathEffect e = new DashPathEffect( 21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new float[] { state.mStrokeDashWidth, state.mStrokeDashGap }, 0); 21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStrokePaint.setPathEffect(e); 21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21413ad771b384b55bc0b9ee9519f457ea7093bb0b74Alan Viverette 2142daec594370f0e47bf07d0c9c968e3c5dfedf0bb5Alan Viverette mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode); 214345c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette mGradientIsDirty = true; 214445c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette 214545c4bbbbce6bbad50a033efcba7948a23f1f117aAlan Viverette state.computeOpacity(); 21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2148