diff --git a/docs/components/BadgeDrawable.md b/docs/components/BadgeDrawable.md
index d40d2461a3b..1bad7fd25da 100644
--- a/docs/components/BadgeDrawable.md
+++ b/docs/components/BadgeDrawable.md
@@ -90,18 +90,20 @@ center, use `setHorizontalOffset(int)` or `setVerticalOffset(int)`
### `BadgeDrawable` Attributes
-| Feature | Relevant attributes |
-| --------------------- | -----------------------------------------------------------------------------------------------------------------|
-| Color | `app:backgroundColor`
`app:badgeTextColor` |
-| Width | `app:badgeWidth`
`app:badgeWithTextWidth` |
-| Height | `app:badgeHeight`
`app:badgeWithTextHeight` |
-| Shape | `app:badgeShapeAppearance`
`app:badgeShapeAppearanceOverlay`
`app:badgeWithTextShapeAppearance`
`app:badgeWithTextShapeAppearanceOverlay` |
-| Label | `app:badgeText` (for text)
`app:number` (for numbers) |
-| Label Length | `app:maxCharacterCount` |
-| Label Text Color | `app:badgeTextColor` |
-| Label Text Appearance | `app:badgeTextAppearance` |
-| Badge Gravity | `app:badgeGravity` |
-| Offset Alignment | `app:offsetAlignmentMode` |
+| Feature | Relevant attributes |
+|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Color | `app:backgroundColor`
`app:badgeTextColor` |
+| Width | `app:badgeWidth`
`app:badgeWithTextWidth` |
+| Height | `app:badgeHeight`
`app:badgeWithTextHeight` |
+| Shape | `app:badgeShapeAppearance`
`app:badgeShapeAppearanceOverlay`
`app:badgeWithTextShapeAppearance`
`app:badgeWithTextShapeAppearanceOverlay` |
+| Label | `app:badgeText` (for text)
`app:number` (for numbers) |
+| Label Length | `app:maxCharacterCount` |
+| Label Text Color | `app:badgeTextColor` |
+| Label Text Appearance | `app:badgeTextAppearance` |
+| Badge Gravity | `app:badgeGravity` |
+| Offset Alignment | `app:offsetAlignmentMode` |
+| Horizontal Padding | `app:badgeWidePadding` |
+| Vertical Padding | `app:badgeVerticalPadding` |
**Note:** If both `app:badgeText` and `app:number` are specified, the badge label will be `app:badgeText`.
diff --git a/lib/java/com/google/android/material/badge/BadgeDrawable.java b/lib/java/com/google/android/material/badge/BadgeDrawable.java
index e2cf2ca567a..3b4204491b1 100644
--- a/lib/java/com/google/android/material/badge/BadgeDrawable.java
+++ b/lib/java/com/google/android/material/badge/BadgeDrawable.java
@@ -783,6 +783,48 @@ private CharSequence getEmptyContentDescription() {
return state.getContentDescriptionNumberless();
}
+ /**
+ * Sets how much (in pixels) horizontal padding to add to the badge when it has label contents.
+ * Note that badges have a minimum width as specified by
+ * com.google.android.material.R.styleable#Badge_badgeWidth.
+ *
+ * @param horizontalPadding badge's horizontal padding
+ * @attr ref com.google.android.material.R.styleable#Badge_badgeWidePadding
+ */
+ public void setHorizontalPadding(@Px int horizontalPadding) {
+ if (horizontalPadding != state.getBadgeHorizontalPadding()) {
+ state.setBadgeHorizontalPadding(horizontalPadding);
+ updateCenterAndBounds();
+ }
+ }
+
+ /** Returns the badge horizontal padding in pixels. */
+ @Px
+ public int getHorizontalPadding() {
+ return state.getBadgeHorizontalPadding();
+ }
+
+ /**
+ * Sets how much (in pixels) vertical padding to add to the badge when it has label contents. Note
+ * that badges have a minimum height as specified by
+ * com.google.android.material.R.styleable#Badge_badgeHeight.
+ *
+ * @param verticalPadding badge's vertical padding
+ * @attr ref com.google.android.material.R.styleable#Badge_badgeVerticalPadding
+ */
+ public void setVerticalPadding(@Px int verticalPadding) {
+ if (verticalPadding != state.getBadgeVerticalPadding()) {
+ state.setBadgeVerticalPadding(verticalPadding);
+ updateCenterAndBounds();
+ }
+ }
+
+ /** Returns the badge vertical padding in pixels. */
+ @Px
+ public int getVerticalPadding() {
+ return state.getBadgeVerticalPadding();
+ }
+
/**
* Sets how much (in pixels) to horizontally move this badge towards the center of its anchor.
*
@@ -1106,7 +1148,8 @@ private void calculateCenterAndBounds(@NonNull Rect anchorRect, @NonNull View an
halfBadgeHeight =
Math.max(
halfBadgeHeight,
- textDrawableHelper.getTextHeight(badgeContent) / 2f + state.badgeVerticalPadding);
+ textDrawableHelper.getTextHeight(badgeContent) / 2f
+ + state.getBadgeVerticalPadding());
// If the badge has text, it should at least have the same width as it does height
halfBadgeWidth = Math.max(halfBadgeWidth, halfBadgeHeight);
@@ -1119,7 +1162,8 @@ private void calculateCenterAndBounds(@NonNull Rect anchorRect, @NonNull View an
halfBadgeWidth =
Math.max(
halfBadgeWidth,
- textDrawableHelper.getTextWidth(badgeContent) / 2f + state.badgeWidePadding);
+ textDrawableHelper.getTextWidth(badgeContent) / 2f
+ + state.getBadgeHorizontalPadding());
}
int totalVerticalOffset = getTotalVerticalOffsetForState();
diff --git a/lib/java/com/google/android/material/badge/BadgeState.java b/lib/java/com/google/android/material/badge/BadgeState.java
index 98f45376c6a..c0e17c7257e 100644
--- a/lib/java/com/google/android/material/badge/BadgeState.java
+++ b/lib/java/com/google/android/material/badge/BadgeState.java
@@ -37,6 +37,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.PluralsRes;
+import androidx.annotation.Px;
import androidx.annotation.RestrictTo;
import androidx.annotation.StringRes;
import androidx.annotation.StyleRes;
@@ -76,8 +77,6 @@ public final class BadgeState {
final float badgeHeight;
final float badgeWithTextWidth;
final float badgeWithTextHeight;
- final float badgeWidePadding;
- final float badgeVerticalPadding;
final int horizontalInset;
final int horizontalInsetWithText;
@@ -102,14 +101,7 @@ public final class BadgeState {
Resources res = context.getResources();
badgeRadius =
a.getDimensionPixelSize(R.styleable.Badge_badgeRadius, BADGE_RADIUS_NOT_SPECIFIED);
- badgeWidePadding =
- a.getDimensionPixelSize(
- R.styleable.Badge_badgeWidePadding,
- res.getDimensionPixelSize(R.dimen.mtrl_badge_long_text_horizontal_padding));
- badgeVerticalPadding =
- a.getDimension(
- R.styleable.Badge_badgeVerticalPadding,
- res.getDimension(R.dimen.m3_badge_with_text_vertical_padding));
+
horizontalInset =
context
.getResources()
@@ -236,6 +228,19 @@ public final class BadgeState {
? a.getInt(R.styleable.Badge_badgeGravity, TOP_END)
: storedState.badgeGravity;
+ currentState.badgeHorizontalPadding =
+ storedState.badgeHorizontalPadding == null
+ ? a.getDimensionPixelSize(
+ R.styleable.Badge_badgeWidePadding,
+ res.getDimensionPixelSize(R.dimen.mtrl_badge_long_text_horizontal_padding))
+ : storedState.badgeHorizontalPadding;
+ currentState.badgeVerticalPadding =
+ storedState.badgeVerticalPadding == null
+ ? a.getDimensionPixelSize(
+ R.styleable.Badge_badgeVerticalPadding,
+ res.getDimensionPixelSize(R.dimen.m3_badge_with_text_vertical_padding))
+ : storedState.badgeVerticalPadding;
+
currentState.horizontalOffsetWithoutText =
storedState.horizontalOffsetWithoutText == null
? a.getDimensionPixelOffset(R.styleable.Badge_horizontalOffset, 0)
@@ -442,6 +447,26 @@ void setBadgeGravity(@BadgeGravity int badgeGravity) {
currentState.badgeGravity = badgeGravity;
}
+ @Px
+ int getBadgeHorizontalPadding() {
+ return currentState.badgeHorizontalPadding;
+ }
+
+ void setBadgeHorizontalPadding(@Px int horizontalPadding) {
+ overridingState.badgeHorizontalPadding = horizontalPadding;
+ currentState.badgeHorizontalPadding = horizontalPadding;
+ }
+
+ @Px
+ int getBadgeVerticalPadding() {
+ return currentState.badgeVerticalPadding;
+ }
+
+ void setBadgeVerticalPadding(@Px int verticalPadding) {
+ overridingState.badgeVerticalPadding = verticalPadding;
+ currentState.badgeVerticalPadding = verticalPadding;
+ }
+
@Dimension(unit = Dimension.PX)
int getHorizontalOffsetWithoutText() {
return currentState.horizontalOffsetWithoutText;
@@ -591,6 +616,10 @@ public static final class State implements Parcelable {
@BadgeGravity private Integer badgeGravity;
private Boolean isVisible = true;
+ @Px private Integer badgeHorizontalPadding;
+
+ @Px private Integer badgeVerticalPadding;
+
@Dimension(unit = Dimension.PX)
private Integer horizontalOffsetWithoutText;
@@ -628,6 +657,8 @@ public State() {}
contentDescriptionNumberless = in.readString();
contentDescriptionQuantityStrings = in.readInt();
badgeGravity = (Integer) in.readSerializable();
+ badgeHorizontalPadding = (Integer) in.readSerializable();
+ badgeVerticalPadding = (Integer) in.readSerializable();
horizontalOffsetWithoutText = (Integer) in.readSerializable();
verticalOffsetWithoutText = (Integer) in.readSerializable();
horizontalOffsetWithText = (Integer) in.readSerializable();
@@ -678,6 +709,8 @@ public void writeToParcel(@NonNull Parcel dest, int flags) {
contentDescriptionNumberless != null ? contentDescriptionNumberless.toString() : null);
dest.writeInt(contentDescriptionQuantityStrings);
dest.writeSerializable(badgeGravity);
+ dest.writeSerializable(badgeHorizontalPadding);
+ dest.writeSerializable(badgeVerticalPadding);
dest.writeSerializable(horizontalOffsetWithoutText);
dest.writeSerializable(verticalOffsetWithoutText);
dest.writeSerializable(horizontalOffsetWithText);
diff --git a/lib/java/com/google/android/material/badge/res-public/values/public.xml b/lib/java/com/google/android/material/badge/res-public/values/public.xml
index 4b58112f6f0..d31a0bbad06 100644
--- a/lib/java/com/google/android/material/badge/res-public/values/public.xml
+++ b/lib/java/com/google/android/material/badge/res-public/values/public.xml
@@ -23,6 +23,8 @@
+
+
diff --git a/lib/javatests/com/google/android/material/badge/BadgeDrawableTest.java b/lib/javatests/com/google/android/material/badge/BadgeDrawableTest.java
index c0da0461a1e..ea476b0718c 100644
--- a/lib/javatests/com/google/android/material/badge/BadgeDrawableTest.java
+++ b/lib/javatests/com/google/android/material/badge/BadgeDrawableTest.java
@@ -50,6 +50,9 @@ public class BadgeDrawableTest {
private static final int TEST_BADGE_HORIZONTAL_OFFSET = 10;
private static final int TEST_BADGE_VERTICAL_OFFSET = 5;
+ private static final int TEST_BADGE_HORIZONTAL_PADDING = 10;
+ private static final int TEST_BADGE_VERTICAL_PADDING = 10;
+
private final Context context = ApplicationProvider.getApplicationContext();
@Before
@@ -70,6 +73,9 @@ public void testSavedState() {
badgeDrawable.setNumber(TEST_BADGE_NUMBER);
badgeDrawable.setBadgeGravity(BadgeDrawable.TOP_START);
+ badgeDrawable.setHorizontalPadding(TEST_BADGE_HORIZONTAL_PADDING);
+ badgeDrawable.setVerticalPadding(TEST_BADGE_VERTICAL_PADDING);
+
badgeDrawable.setHorizontalOffset(TEST_BADGE_HORIZONTAL_OFFSET);
badgeDrawable.setVerticalOffset(TEST_BADGE_VERTICAL_OFFSET);
@@ -104,6 +110,9 @@ public void testSavedState() {
assertThat(restoredBadgeDrawable.getAlpha()).isEqualTo(255);
assertThat(restoredBadgeDrawable.getMaxCharacterCount()).isEqualTo(4);
assertThat(restoredBadgeDrawable.getBadgeGravity()).isEqualTo(BadgeDrawable.TOP_START);
+ // badge padding
+ assertThat(restoredBadgeDrawable.getHorizontalPadding()).isEqualTo(TEST_BADGE_HORIZONTAL_PADDING);
+ assertThat(restoredBadgeDrawable.getVerticalPadding()).isEqualTo(TEST_BADGE_VERTICAL_PADDING);
// badge offsets
assertThat(restoredBadgeDrawable.getHorizontalOffset()).isEqualTo(TEST_BADGE_HORIZONTAL_OFFSET);
assertThat(restoredBadgeDrawable.getVerticalOffset()).isEqualTo(TEST_BADGE_VERTICAL_OFFSET);