@@ -435,7 +435,8 @@ public void draw(Canvas canvas) {
435435 final int currFillAlpha = modulateAlpha (prevFillAlpha );
436436 final int currStrokeAlpha = modulateAlpha (prevStrokeAlpha );
437437
438- final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint .getStrokeWidth () > 0 ;
438+ final boolean haveStroke = currStrokeAlpha > 0 && mStrokePaint != null &&
439+ mStrokePaint .getStrokeWidth () > 0 ;
439440 final boolean haveFill = currFillAlpha > 0 ;
440441 final GradientState st = mGradientState ;
441442 /* we need a layer iff we're drawing both a fill and stroke, and the
@@ -603,9 +604,9 @@ private Path buildRing(GradientState st) {
603604
604605 /**
605606 * <p>Changes this drawbale to use a single color instead of a gradient.</p>
606- * <p><strong>Note</strong>: changing orientation will affect all instances
607+ * <p><strong>Note</strong>: changing color will affect all instances
607608 * of a drawable loaded from a resource. It is recommended to invoke
608- * {@link #mutate()} before changing the orientation .</p>
609+ * {@link #mutate()} before changing the color .</p>
609610 *
610611 * @param argb The color used to fill the shape
611612 *
@@ -649,7 +650,7 @@ public void setColorFilter(ColorFilter cf) {
649650
650651 @ Override
651652 public int getOpacity () {
652- return PixelFormat .TRANSLUCENT ;
653+ return mGradientState . mOpaque ? PixelFormat . OPAQUE : PixelFormat .TRANSLUCENT ;
653654 }
654655
655656 @ Override
@@ -1011,7 +1012,10 @@ public void inflate(Resources r, XmlPullParser parser,
10111012 } else {
10121013 Log .w ("drawable" , "Bad element under <shape>: " + name );
10131014 }
1015+
10141016 }
1017+
1018+ mGradientState .computeOpacity ();
10151019 }
10161020
10171021 private static float getFloatOrFraction (TypedArray a , int index , float defaultValue ) {
@@ -1079,10 +1083,11 @@ final static class GradientState extends ConstantState {
10791083 private float mGradientRadius = 0.5f ;
10801084 private boolean mUseLevel ;
10811085 private boolean mUseLevelForShape ;
1086+ private boolean mOpaque ;
10821087
10831088 GradientState (Orientation orientation , int [] colors ) {
10841089 mOrientation = orientation ;
1085- mColors = colors ;
1090+ setColors ( colors ) ;
10861091 }
10871092
10881093 public GradientState (GradientState state ) {
@@ -1120,6 +1125,7 @@ public GradientState(GradientState state) {
11201125 mGradientRadius = state .mGradientRadius ;
11211126 mUseLevel = state .mUseLevel ;
11221127 mUseLevelForShape = state .mUseLevelForShape ;
1128+ mOpaque = state .mOpaque ;
11231129 }
11241130
11251131 @ Override
@@ -1139,6 +1145,7 @@ public int getChangingConfigurations() {
11391145
11401146 public void setShape (int shape ) {
11411147 mShape = shape ;
1148+ computeOpacity ();
11421149 }
11431150
11441151 public void setGradientType (int gradient ) {
@@ -1153,24 +1160,60 @@ public void setGradientCenter(float x, float y) {
11531160 public void setColors (int [] colors ) {
11541161 mHasSolidColor = false ;
11551162 mColors = colors ;
1163+ computeOpacity ();
11561164 }
11571165
11581166 public void setSolidColor (int argb ) {
11591167 mHasSolidColor = true ;
11601168 mSolidColor = argb ;
11611169 mColors = null ;
1170+ computeOpacity ();
1171+ }
1172+
1173+ private void computeOpacity () {
1174+ if (mShape != RECTANGLE ) {
1175+ mOpaque = false ;
1176+ return ;
1177+ }
1178+
1179+ if (mStrokeWidth > 0 && !isOpaque (mStrokeColor )) {
1180+ mOpaque = false ;
1181+ return ;
1182+ }
1183+
1184+ if (mHasSolidColor ) {
1185+ mOpaque = isOpaque (mSolidColor );
1186+ return ;
1187+ }
1188+
1189+ if (mColors != null ) {
1190+ for (int i = 0 ; i < mColors .length ; i ++) {
1191+ if (!isOpaque (mColors [i ])) {
1192+ mOpaque = false ;
1193+ return ;
1194+ }
1195+ }
1196+ }
1197+
1198+ mOpaque = true ;
1199+ }
1200+
1201+ private static boolean isOpaque (int color ) {
1202+ return ((color >> 24 ) & 0xff ) == 0xff ;
11621203 }
11631204
11641205 public void setStroke (int width , int color ) {
11651206 mStrokeWidth = width ;
11661207 mStrokeColor = color ;
1208+ computeOpacity ();
11671209 }
1168-
1210+
11691211 public void setStroke (int width , int color , float dashWidth , float dashGap ) {
11701212 mStrokeWidth = width ;
11711213 mStrokeColor = color ;
11721214 mStrokeDashWidth = dashWidth ;
11731215 mStrokeDashGap = dashGap ;
1216+ computeOpacity ();
11741217 }
11751218
11761219 public void setCornerRadius (float radius ) {
@@ -1180,14 +1223,14 @@ public void setCornerRadius(float radius) {
11801223 mRadius = radius ;
11811224 mRadiusArray = null ;
11821225 }
1183-
1226+
11841227 public void setCornerRadii (float [] radii ) {
11851228 mRadiusArray = radii ;
11861229 if (radii == null ) {
11871230 mRadius = 0 ;
11881231 }
11891232 }
1190-
1233+
11911234 public void setSize (int width , int height ) {
11921235 mWidth = width ;
11931236 mHeight = height ;
0 commit comments