Skip to content

Commit b8f2dd5

Browse files
drchenjosefigueroa168
authored andcommitted
[Badge] Support different locale on badges
Resolves #2465 PiperOrigin-RevId: 413738198
1 parent 9980596 commit b8f2dd5

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

lib/java/com/google/android/material/badge/BadgeDrawable.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import android.graphics.PixelFormat;
3232
import android.graphics.Rect;
3333
import android.graphics.drawable.Drawable;
34+
import android.os.Build.VERSION;
35+
import android.os.Build.VERSION_CODES;
3436
import android.os.Parcel;
3537
import android.os.Parcelable;
3638
import android.util.AttributeSet;
@@ -64,6 +66,7 @@
6466
import java.lang.annotation.RetentionPolicy;
6567
import java.lang.ref.WeakReference;
6668
import java.text.NumberFormat;
69+
import java.util.Locale;
6770

6871
/**
6972
* {@code BadgeDrawable} contains all the layout and draw logic for a badge.
@@ -210,6 +213,7 @@ public static final class SavedState implements Parcelable {
210213
@StringRes private int contentDescriptionExceedsMaxBadgeNumberRes;
211214
@BadgeGravity private int badgeGravity;
212215
private boolean isVisible;
216+
private Locale numberLocale;
213217

214218
@Dimension(unit = Dimension.PX)
215219
private int horizontalOffsetWithoutText;
@@ -241,6 +245,10 @@ public SavedState(@NonNull Context context) {
241245
contentDescriptionExceedsMaxBadgeNumberRes =
242246
R.string.mtrl_exceed_max_badge_number_content_description;
243247
isVisible = true;
248+
numberLocale =
249+
VERSION.SDK_INT >= VERSION_CODES.N
250+
? Locale.getDefault(Locale.Category.FORMAT)
251+
: Locale.getDefault();
244252
}
245253

246254
protected SavedState(@NonNull Parcel in) {
@@ -259,6 +267,7 @@ protected SavedState(@NonNull Parcel in) {
259267
additionalHorizontalOffset = in.readInt();
260268
additionalVerticalOffset = in.readInt();
261269
isVisible = in.readInt() != 0;
270+
numberLocale = (Locale) in.readSerializable();
262271
}
263272

264273
public static final Creator<SavedState> CREATOR =
@@ -298,6 +307,7 @@ public void writeToParcel(@NonNull Parcel dest, int flags) {
298307
dest.writeInt(additionalHorizontalOffset);
299308
dest.writeInt(additionalVerticalOffset);
300309
dest.writeInt(isVisible ? 1 : 0);
310+
dest.writeSerializable(numberLocale);
301311
}
302312
}
303313

@@ -371,6 +381,7 @@ public void setVisible(boolean visible) {
371381

372382
private void restoreFromSavedState(@NonNull SavedState savedState) {
373383
setMaxCharacterCount(savedState.maxCharacterCount);
384+
setBadgeNumberLocale(savedState.numberLocale);
374385

375386
// Only set the badge number if it exists in the style.
376387
// Defaulting it to 0 means the badge will incorrectly show text when the user may want a
@@ -647,6 +658,20 @@ public void setBadgeTextColor(@ColorInt int badgeTextColor) {
647658
}
648659
}
649660

661+
/** Returns the {@link Locale} used to show badge numbers. */
662+
@NonNull
663+
public Locale getBadgeNumberLocale() {
664+
return savedState.numberLocale;
665+
}
666+
667+
/** Sets the {@link Locale} used to show badge numbers. */
668+
public void setBadgeNumberLocale(@NonNull Locale locale) {
669+
if (!locale.equals(savedState.numberLocale)) {
670+
savedState.numberLocale = locale;
671+
invalidateSelf();
672+
}
673+
}
674+
650675
/** Returns whether this badge will display a number. */
651676
public boolean hasNumber() {
652677
return savedState.number != BADGE_NUMBER_NONE;
@@ -1137,15 +1162,16 @@ private void drawText(Canvas canvas) {
11371162
private String getBadgeText() {
11381163
// If number exceeds max count, show badgeMaxCount+ instead of the number.
11391164
if (getNumber() <= maxBadgeNumber) {
1140-
return NumberFormat.getInstance().format(getNumber());
1165+
return NumberFormat.getInstance(savedState.numberLocale).format(getNumber());
11411166
} else {
11421167
Context context = contextRef.get();
11431168
if (context == null) {
11441169
return "";
11451170
}
11461171

1147-
return context.getString(
1148-
R.string.mtrl_exceed_max_badge_number_suffix,
1172+
return String.format(
1173+
savedState.numberLocale,
1174+
context.getString(R.string.mtrl_exceed_max_badge_number_suffix),
11491175
maxBadgeNumber,
11501176
DEFAULT_EXCEED_MAX_BADGE_NUMBER_SUFFIX);
11511177
}

lib/javatests/com/google/android/material/badge/BadgeDrawableTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import androidx.test.core.app.ApplicationProvider;
3232
import com.google.android.material.badge.BadgeDrawable.SavedState;
3333
import com.google.android.material.drawable.DrawableUtils;
34+
import java.util.Locale;
3435
import org.junit.Before;
3536
import org.junit.Test;
3637
import org.junit.runner.RunWith;
@@ -44,6 +45,7 @@
4445
public class BadgeDrawableTest {
4546

4647
private static final int TEST_BADGE_NUMBER = 26;
48+
private static final Locale TEST_BADGE_NUMBER_LOCALE = new Locale("ar");
4749

4850
private static final int TEST_BADGE_HORIZONTAL_OFFSET = 10;
4951
private static final int TEST_BADGE_VERTICAL_OFFSET = 5;
@@ -84,6 +86,7 @@ public void testSavedState() {
8486
badgeDrawable.setBackgroundColor(testBackgroundColor);
8587
badgeDrawable.setBadgeTextColor(testBadgeTextColor);
8688
badgeDrawable.setVisible(false);
89+
badgeDrawable.setBadgeNumberLocale(TEST_BADGE_NUMBER_LOCALE);
8790

8891
Parcel parcel = Parcel.obtain();
8992
drawableState.writeToParcel(parcel, drawableState.describeContents());
@@ -110,6 +113,9 @@ public void testSavedState() {
110113

111114
// badge visibility
112115
assertThat(restoredBadgeDrawable.isVisible()).isFalse();
116+
117+
// badge number locale
118+
assertThat(restoredBadgeDrawable.getBadgeNumberLocale()).isEqualTo(TEST_BADGE_NUMBER_LOCALE);
113119
}
114120

115121
// Verify that the hardcoded badge gravity attribute values match their piped Gravity counter

0 commit comments

Comments
 (0)