|
33 | 33 | import android.os.Build.VERSION_CODES; |
34 | 34 | import androidx.core.graphics.drawable.DrawableCompat; |
35 | 35 | import androidx.core.view.ViewCompat; |
| 36 | +import androidx.annotation.ChecksSdkIntAtLeast; |
36 | 37 | import androidx.annotation.Dimension; |
37 | 38 | import androidx.annotation.NonNull; |
38 | 39 | import androidx.annotation.Nullable; |
|
50 | 51 | @RestrictTo(LIBRARY_GROUP) |
51 | 52 | class MaterialButtonHelper { |
52 | 53 |
|
53 | | - private static final boolean IS_LOLLIPOP = VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP; |
| 54 | + @ChecksSdkIntAtLeast(api = VERSION_CODES.LOLLIPOP) |
| 55 | + private static final boolean IS_MIN_LOLLIPOP = VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP; |
| 56 | + |
| 57 | + private static final boolean IS_LOLLIPOP = |
| 58 | + VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP && VERSION.SDK_INT <= VERSION_CODES.LOLLIPOP_MR1; |
54 | 59 | private final MaterialButton materialButton; |
55 | 60 | @NonNull private ShapeAppearanceModel shapeAppearanceModel; |
56 | 61 |
|
@@ -218,7 +223,7 @@ private Drawable createBackground() { |
218 | 223 | ? MaterialColors.getColor(materialButton, R.attr.colorSurface) |
219 | 224 | : Color.TRANSPARENT); |
220 | 225 |
|
221 | | - if (IS_LOLLIPOP) { |
| 226 | + if (IS_MIN_LOLLIPOP) { |
222 | 227 | maskDrawable = new MaterialShapeDrawable(shapeAppearanceModel); |
223 | 228 | DrawableCompat.setTint(maskDrawable, Color.WHITE); |
224 | 229 | rippleDrawable = |
@@ -255,12 +260,13 @@ void setBackgroundColor(int color) { |
255 | 260 | void setRippleColor(@Nullable ColorStateList rippleColor) { |
256 | 261 | if (this.rippleColor != rippleColor) { |
257 | 262 | this.rippleColor = rippleColor; |
258 | | - if (IS_LOLLIPOP && materialButton.getBackground() instanceof RippleDrawable) { |
| 263 | + if (IS_MIN_LOLLIPOP && materialButton.getBackground() instanceof RippleDrawable) { |
259 | 264 | ((RippleDrawable) materialButton.getBackground()) |
260 | 265 | .setColor(RippleUtils.sanitizeRippleDrawableColor(rippleColor)); |
261 | | - } else if (!IS_LOLLIPOP && materialButton.getBackground() instanceof RippleDrawableCompat) { |
262 | | - ((RippleDrawableCompat) materialButton.getBackground()).setTintList( |
263 | | - RippleUtils.sanitizeRippleDrawableColor(rippleColor)); |
| 266 | + } else if (!IS_MIN_LOLLIPOP |
| 267 | + && materialButton.getBackground() instanceof RippleDrawableCompat) { |
| 268 | + ((RippleDrawableCompat) materialButton.getBackground()) |
| 269 | + .setTintList(RippleUtils.sanitizeRippleDrawableColor(rippleColor)); |
264 | 270 | } |
265 | 271 | } |
266 | 272 | } |
@@ -326,7 +332,7 @@ int getCornerRadius() { |
326 | 332 | @Nullable |
327 | 333 | private MaterialShapeDrawable getMaterialShapeDrawable(boolean getSurfaceColorStrokeDrawable) { |
328 | 334 | if (rippleDrawable != null && rippleDrawable.getNumberOfLayers() > 0) { |
329 | | - if (IS_LOLLIPOP) { |
| 335 | + if (IS_MIN_LOLLIPOP) { |
330 | 336 | InsetDrawable insetDrawable = (InsetDrawable) rippleDrawable.getDrawable(0); |
331 | 337 | LayerDrawable layerDrawable = (LayerDrawable) insetDrawable.getDrawable(); |
332 | 338 | return (MaterialShapeDrawable) |
@@ -359,14 +365,28 @@ private MaterialShapeDrawable getSurfaceColorStrokeDrawable() { |
359 | 365 | } |
360 | 366 |
|
361 | 367 | private void updateButtonShape(@NonNull ShapeAppearanceModel shapeAppearanceModel) { |
362 | | - if (getMaterialShapeDrawable() != null) { |
363 | | - getMaterialShapeDrawable().setShapeAppearanceModel(shapeAppearanceModel); |
364 | | - } |
365 | | - if (getSurfaceColorStrokeDrawable() != null) { |
366 | | - getSurfaceColorStrokeDrawable().setShapeAppearanceModel(shapeAppearanceModel); |
367 | | - } |
368 | | - if (getMaskDrawable() != null) { |
369 | | - getMaskDrawable().setShapeAppearanceModel(shapeAppearanceModel); |
| 368 | + // There seems to be a bug to drawables that is affecting Lollipop, since invalidation is not |
| 369 | + // changing an existing drawable shape. This is a fallback. |
| 370 | + if (IS_LOLLIPOP && !backgroundOverwritten) { |
| 371 | + // Store padding before setting background, since background overwrites padding values |
| 372 | + int paddingStart = ViewCompat.getPaddingStart(materialButton); |
| 373 | + int paddingTop = materialButton.getPaddingTop(); |
| 374 | + int paddingEnd = ViewCompat.getPaddingEnd(materialButton); |
| 375 | + int paddingBottom = materialButton.getPaddingBottom(); |
| 376 | + updateBackground(); |
| 377 | + // Set the stored padding values |
| 378 | + ViewCompat.setPaddingRelative( |
| 379 | + materialButton, paddingStart, paddingTop, paddingEnd, paddingBottom); |
| 380 | + } else { |
| 381 | + if (getMaterialShapeDrawable() != null) { |
| 382 | + getMaterialShapeDrawable().setShapeAppearanceModel(shapeAppearanceModel); |
| 383 | + } |
| 384 | + if (getSurfaceColorStrokeDrawable() != null) { |
| 385 | + getSurfaceColorStrokeDrawable().setShapeAppearanceModel(shapeAppearanceModel); |
| 386 | + } |
| 387 | + if (getMaskDrawable() != null) { |
| 388 | + getMaskDrawable().setShapeAppearanceModel(shapeAppearanceModel); |
| 389 | + } |
370 | 390 | } |
371 | 391 | } |
372 | 392 |
|
@@ -431,5 +451,4 @@ private void setVerticalInsets(@Dimension int newInsetTop, @Dimension int newIns |
431 | 451 | public int getInsetTop() { |
432 | 452 | return insetTop; |
433 | 453 | } |
434 | | - |
435 | 454 | } |
0 commit comments