Skip to content

Commit 19d0500

Browse files
committedApr 11, 2022
[Button] Fix icon position with multiline text
When the icon gravity is textTop, we are using the smaller one of the calculated height from text paint and the text layout height to decide the icon position. This is wrong when there are multiple lines of text since the text paint is always single line and always shorter than the actual height. Fixes this by returning the actual layout height whenever there are multiple lines of text to fix the issue. Resolves #2619 PiperOrigin-RevId: 440923733
1 parent dc0d8a9 commit 19d0500

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed
 

‎lib/java/com/google/android/material/button/MaterialButton.java

+17-9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
2222
import static com.google.android.material.theme.overlay.MaterialThemeOverlay.wrap;
23+
import static java.lang.Math.max;
24+
import static java.lang.Math.min;
2325

2426
import android.content.Context;
2527
import android.content.res.ColorStateList;
@@ -593,13 +595,15 @@ private void updateIconPosition(int buttonWidth, int buttonHeight) {
593595

594596
int localIconSize = iconSize == 0 ? icon.getIntrinsicHeight() : iconSize;
595597
int newIconTop =
596-
(buttonHeight
597-
- getTextHeight()
598-
- getPaddingTop()
599-
- localIconSize
600-
- iconPadding
601-
- getPaddingBottom())
602-
/ 2;
598+
max(
599+
0, // Always put the icon on top if the content height is taller than the button.
600+
(buttonHeight
601+
- getTextHeight()
602+
- getPaddingTop()
603+
- localIconSize
604+
- iconPadding
605+
- getPaddingBottom())
606+
/ 2);
603607

604608
if (iconTop != newIconTop) {
605609
iconTop = newIconTop;
@@ -617,10 +621,14 @@ private int getTextWidth() {
617621
buttonText = getTransformationMethod().getTransformation(buttonText, this).toString();
618622
}
619623

620-
return Math.min((int) textPaint.measureText(buttonText), getLayout().getEllipsizedWidth());
624+
return min((int) textPaint.measureText(buttonText), getLayout().getEllipsizedWidth());
621625
}
622626

623627
private int getTextHeight() {
628+
if (getLineCount() > 1) {
629+
// If it's multi-line, return the internal text layout's height.
630+
return getLayout().getHeight();
631+
}
624632
Paint textPaint = getPaint();
625633
String buttonText = getText().toString();
626634
if (getTransformationMethod() != null) {
@@ -632,7 +640,7 @@ private int getTextHeight() {
632640
Rect bounds = new Rect();
633641
textPaint.getTextBounds(buttonText, 0, buttonText.length(), bounds);
634642

635-
return Math.min(bounds.height(), getLayout().getHeight());
643+
return min(bounds.height(), getLayout().getHeight());
636644
}
637645

638646
private boolean isLayoutRTL() {

0 commit comments

Comments
 (0)
Please sign in to comment.