|
47 | 47 | import androidx.annotation.NonNull; |
48 | 48 | import androidx.annotation.Nullable; |
49 | 49 | import androidx.annotation.PluralsRes; |
| 50 | +import androidx.annotation.Px; |
50 | 51 | import androidx.annotation.RestrictTo; |
51 | 52 | import androidx.annotation.StringRes; |
52 | 53 | import androidx.annotation.StyleRes; |
@@ -175,9 +176,9 @@ public class BadgeDrawable extends Drawable implements TextDrawableDelegate { |
175 | 176 | @NonNull private final MaterialShapeDrawable shapeDrawable; |
176 | 177 | @NonNull private final TextDrawableHelper textDrawableHelper; |
177 | 178 | @NonNull private final Rect badgeBounds; |
178 | | - private final float badgeRadius; |
179 | | - private final float badgeWithTextRadius; |
180 | | - private final float badgeWidePadding; |
| 179 | + private float badgeRadius; |
| 180 | + private float badgeWithTextRadius; |
| 181 | + private float badgeWidePadding; |
181 | 182 | @NonNull private final SavedState savedState; |
182 | 183 |
|
183 | 184 | private float badgeCenterX; |
@@ -216,6 +217,12 @@ public static final class SavedState implements Parcelable { |
216 | 217 | @Dimension(unit = Dimension.PX) |
217 | 218 | private int verticalOffset; |
218 | 219 |
|
| 220 | + @Dimension(unit = Dimension.PX) |
| 221 | + private int horizontalOffsetWithText; |
| 222 | + |
| 223 | + @Dimension(unit = Dimension.PX) |
| 224 | + private int verticalOffsetWithText; |
| 225 | + |
219 | 226 | @Dimension(unit = Dimension.PX) |
220 | 227 | private int additionalHorizontalOffset; |
221 | 228 |
|
@@ -247,6 +254,8 @@ protected SavedState(@NonNull Parcel in) { |
247 | 254 | badgeGravity = in.readInt(); |
248 | 255 | horizontalOffset = in.readInt(); |
249 | 256 | verticalOffset = in.readInt(); |
| 257 | + horizontalOffsetWithText = in.readInt(); |
| 258 | + verticalOffsetWithText = in.readInt(); |
250 | 259 | additionalHorizontalOffset = in.readInt(); |
251 | 260 | additionalVerticalOffset = in.readInt(); |
252 | 261 | isVisible = in.readInt() != 0; |
@@ -284,6 +293,8 @@ public void writeToParcel(@NonNull Parcel dest, int flags) { |
284 | 293 | dest.writeInt(badgeGravity); |
285 | 294 | dest.writeInt(horizontalOffset); |
286 | 295 | dest.writeInt(verticalOffset); |
| 296 | + dest.writeInt(horizontalOffsetWithText); |
| 297 | + dest.writeInt(verticalOffsetWithText); |
287 | 298 | dest.writeInt(additionalHorizontalOffset); |
288 | 299 | dest.writeInt(additionalVerticalOffset); |
289 | 300 | dest.writeInt(isVisible ? 1 : 0); |
@@ -379,6 +390,9 @@ private void restoreFromSavedState(@NonNull SavedState savedState) { |
379 | 390 | setHorizontalOffset(savedState.horizontalOffset); |
380 | 391 | setVerticalOffset(savedState.verticalOffset); |
381 | 392 |
|
| 393 | + setHorizontalOffsetWithText(savedState.horizontalOffsetWithText); |
| 394 | + setVerticalOffsetWithText(savedState.verticalOffsetWithText); |
| 395 | + |
382 | 396 | setAdditionalHorizontalOffset(savedState.additionalHorizontalOffset); |
383 | 397 | setAdditionalVerticalOffset(savedState.additionalVerticalOffset); |
384 | 398 |
|
@@ -414,6 +428,25 @@ private void loadDefaultStateFromAttributes( |
414 | 428 | setHorizontalOffset(a.getDimensionPixelOffset(R.styleable.Badge_horizontalOffset, 0)); |
415 | 429 | setVerticalOffset(a.getDimensionPixelOffset(R.styleable.Badge_verticalOffset, 0)); |
416 | 430 |
|
| 431 | + // Set the offsets when the badge has text. Default to using the badge "dot" offsets |
| 432 | + // (horizontalOffset and verticalOffset) if there is no offsets defined for badges with text. |
| 433 | + setHorizontalOffsetWithText( |
| 434 | + a.getDimensionPixelOffset( |
| 435 | + R.styleable.Badge_horizontalOffsetWithText, getHorizontalOffset())); |
| 436 | + setVerticalOffsetWithText( |
| 437 | + a.getDimensionPixelOffset(R.styleable.Badge_verticalOffsetWithText, getVerticalOffset())); |
| 438 | + |
| 439 | + if (a.hasValue(R.styleable.Badge_badgeRadius)) { |
| 440 | + badgeRadius = a.getDimension(R.styleable.Badge_badgeRadius, badgeRadius); |
| 441 | + } |
| 442 | + if (a.hasValue(R.styleable.Badge_badgeWidePadding)) { |
| 443 | + badgeWidePadding = a.getDimension(R.styleable.Badge_badgeWidePadding, badgeWidePadding); |
| 444 | + } |
| 445 | + if (a.hasValue(R.styleable.Badge_badgeWithTextRadius)) { |
| 446 | + badgeWithTextRadius = |
| 447 | + a.getDimension(R.styleable.Badge_badgeWithTextRadius, badgeWithTextRadius); |
| 448 | + } |
| 449 | + |
417 | 450 | a.recycle(); |
418 | 451 | } |
419 | 452 |
|
@@ -827,6 +860,26 @@ public int getHorizontalOffset() { |
827 | 860 | return savedState.horizontalOffset; |
828 | 861 | } |
829 | 862 |
|
| 863 | + /** |
| 864 | + * Sets how much (in pixels) to horizontally move this badge towards the center of its anchor |
| 865 | + * when this badge has text. |
| 866 | + * |
| 867 | + * @param px badge's horizontal offset when the badge has text. |
| 868 | + */ |
| 869 | + public void setHorizontalOffsetWithText(@Px int px) { |
| 870 | + savedState.horizontalOffsetWithText = px; |
| 871 | + updateCenterAndBounds(); |
| 872 | + } |
| 873 | + |
| 874 | + /** |
| 875 | + * Returns how much (in pixels) this badge is being horizontally offset towards the center of its |
| 876 | + * anchor when this badge has text. |
| 877 | + */ |
| 878 | + @Px |
| 879 | + public int getHorizontalOffsetWithText() { |
| 880 | + return savedState.horizontalOffsetWithText; |
| 881 | + } |
| 882 | + |
830 | 883 | /** |
831 | 884 | * Sets how much (in pixels) more (in addition to {@code savedState.horizontalOffset}) to |
832 | 885 | * horizontally move this badge towards the center of its anchor. Currently used to adjust the |
@@ -859,6 +912,26 @@ public int getVerticalOffset() { |
859 | 912 | return savedState.verticalOffset; |
860 | 913 | } |
861 | 914 |
|
| 915 | + /** |
| 916 | + * Sets how much (in pixels) to vertically move this badge towards the center of its anchor when |
| 917 | + * this badge has text. |
| 918 | + * |
| 919 | + * @param px badge's vertical offset when the badge has text. |
| 920 | + */ |
| 921 | + public void setVerticalOffsetWithText(@Px int px) { |
| 922 | + savedState.verticalOffsetWithText = px; |
| 923 | + updateCenterAndBounds(); |
| 924 | + } |
| 925 | + |
| 926 | + /** |
| 927 | + * Returns how much (in pixels) this badge is being vertically moved towards the center of its |
| 928 | + * anchor when the badge has text. |
| 929 | + */ |
| 930 | + @Px |
| 931 | + public int getVerticalOffsetWithText() { |
| 932 | + return savedState.verticalOffsetWithText; |
| 933 | + } |
| 934 | + |
862 | 935 | /** |
863 | 936 | * Sets how much (in pixels) more (in addition to {@code savedState.verticalOffset}) to vertically |
864 | 937 | * move this badge towards the center of its anchor. Currently used to adjust the placement of |
@@ -924,9 +997,19 @@ private void updateCenterAndBounds() { |
924 | 997 | } |
925 | 998 | } |
926 | 999 |
|
| 1000 | + private int getTotalVerticalOffsetForState() { |
| 1001 | + int vOffset = hasNumber() ? savedState.verticalOffsetWithText : savedState.verticalOffset; |
| 1002 | + return vOffset + savedState.additionalVerticalOffset; |
| 1003 | + } |
| 1004 | + |
| 1005 | + private int getTotalHorizontalOffsetForState() { |
| 1006 | + int hOffset = hasNumber() ? savedState.horizontalOffsetWithText : savedState.horizontalOffset; |
| 1007 | + return hOffset + savedState.additionalHorizontalOffset; |
| 1008 | + } |
| 1009 | + |
927 | 1010 | private void calculateCenterAndBounds( |
928 | 1011 | @NonNull Context context, @NonNull Rect anchorRect, @NonNull View anchorView) { |
929 | | - int totalVerticalOffset = savedState.verticalOffset + savedState.additionalVerticalOffset; |
| 1012 | + int totalVerticalOffset = getTotalVerticalOffsetForState(); |
930 | 1013 | switch (savedState.badgeGravity) { |
931 | 1014 | case BOTTOM_END: |
932 | 1015 | case BOTTOM_START: |
@@ -958,7 +1041,7 @@ private void calculateCenterAndBounds( |
958 | 1041 | ? R.dimen.mtrl_badge_text_horizontal_edge_offset |
959 | 1042 | : R.dimen.mtrl_badge_horizontal_edge_offset); |
960 | 1043 |
|
961 | | - int totalHorizontalOffset = savedState.horizontalOffset + savedState.additionalHorizontalOffset; |
| 1044 | + int totalHorizontalOffset = getTotalHorizontalOffsetForState(); |
962 | 1045 |
|
963 | 1046 | // Update the centerX based on the badge width and 'inset' from start or end boundary of anchor. |
964 | 1047 | switch (savedState.badgeGravity) { |
|
0 commit comments