Skip to content

Commit

Permalink
[Badge] Support different locale on badges
Browse files Browse the repository at this point in the history
Resolves #2465

PiperOrigin-RevId: 413738198
  • Loading branch information
drchen authored and josefigueroa168 committed Dec 6, 2021
1 parent 9980596 commit b8f2dd5
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
32 changes: 29 additions & 3 deletions lib/java/com/google/android/material/badge/BadgeDrawable.java
Expand Up @@ -31,6 +31,8 @@
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
Expand Down Expand Up @@ -64,6 +66,7 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.text.NumberFormat;
import java.util.Locale;

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

@Dimension(unit = Dimension.PX)
private int horizontalOffsetWithoutText;
Expand Down Expand Up @@ -241,6 +245,10 @@ public SavedState(@NonNull Context context) {
contentDescriptionExceedsMaxBadgeNumberRes =
R.string.mtrl_exceed_max_badge_number_content_description;
isVisible = true;
numberLocale =
VERSION.SDK_INT >= VERSION_CODES.N
? Locale.getDefault(Locale.Category.FORMAT)
: Locale.getDefault();
}

protected SavedState(@NonNull Parcel in) {
Expand All @@ -259,6 +267,7 @@ protected SavedState(@NonNull Parcel in) {
additionalHorizontalOffset = in.readInt();
additionalVerticalOffset = in.readInt();
isVisible = in.readInt() != 0;
numberLocale = (Locale) in.readSerializable();
}

public static final Creator<SavedState> CREATOR =
Expand Down Expand Up @@ -298,6 +307,7 @@ public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(additionalHorizontalOffset);
dest.writeInt(additionalVerticalOffset);
dest.writeInt(isVisible ? 1 : 0);
dest.writeSerializable(numberLocale);
}
}

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

private void restoreFromSavedState(@NonNull SavedState savedState) {
setMaxCharacterCount(savedState.maxCharacterCount);
setBadgeNumberLocale(savedState.numberLocale);

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

/** Returns the {@link Locale} used to show badge numbers. */
@NonNull
public Locale getBadgeNumberLocale() {
return savedState.numberLocale;
}

/** Sets the {@link Locale} used to show badge numbers. */
public void setBadgeNumberLocale(@NonNull Locale locale) {
if (!locale.equals(savedState.numberLocale)) {
savedState.numberLocale = locale;
invalidateSelf();
}
}

/** Returns whether this badge will display a number. */
public boolean hasNumber() {
return savedState.number != BADGE_NUMBER_NONE;
Expand Down Expand Up @@ -1137,15 +1162,16 @@ private void drawText(Canvas canvas) {
private String getBadgeText() {
// If number exceeds max count, show badgeMaxCount+ instead of the number.
if (getNumber() <= maxBadgeNumber) {
return NumberFormat.getInstance().format(getNumber());
return NumberFormat.getInstance(savedState.numberLocale).format(getNumber());
} else {
Context context = contextRef.get();
if (context == null) {
return "";
}

return context.getString(
R.string.mtrl_exceed_max_badge_number_suffix,
return String.format(
savedState.numberLocale,
context.getString(R.string.mtrl_exceed_max_badge_number_suffix),
maxBadgeNumber,
DEFAULT_EXCEED_MAX_BADGE_NUMBER_SUFFIX);
}
Expand Down
Expand Up @@ -31,6 +31,7 @@
import androidx.test.core.app.ApplicationProvider;
import com.google.android.material.badge.BadgeDrawable.SavedState;
import com.google.android.material.drawable.DrawableUtils;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand All @@ -44,6 +45,7 @@
public class BadgeDrawableTest {

private static final int TEST_BADGE_NUMBER = 26;
private static final Locale TEST_BADGE_NUMBER_LOCALE = new Locale("ar");

private static final int TEST_BADGE_HORIZONTAL_OFFSET = 10;
private static final int TEST_BADGE_VERTICAL_OFFSET = 5;
Expand Down Expand Up @@ -84,6 +86,7 @@ public void testSavedState() {
badgeDrawable.setBackgroundColor(testBackgroundColor);
badgeDrawable.setBadgeTextColor(testBadgeTextColor);
badgeDrawable.setVisible(false);
badgeDrawable.setBadgeNumberLocale(TEST_BADGE_NUMBER_LOCALE);

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

// badge visibility
assertThat(restoredBadgeDrawable.isVisible()).isFalse();

// badge number locale
assertThat(restoredBadgeDrawable.getBadgeNumberLocale()).isEqualTo(TEST_BADGE_NUMBER_LOCALE);
}

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

0 comments on commit b8f2dd5

Please sign in to comment.