Skip to content

Commit

Permalink
[Button] Fix icon position with multiline text
Browse files Browse the repository at this point in the history
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
  • Loading branch information
drchen committed Apr 11, 2022
1 parent dc0d8a9 commit 19d0500
Showing 1 changed file with 17 additions and 9 deletions.
26 changes: 17 additions & 9 deletions lib/java/com/google/android/material/button/MaterialButton.java
Expand Up @@ -20,6 +20,8 @@

import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import static com.google.android.material.theme.overlay.MaterialThemeOverlay.wrap;
import static java.lang.Math.max;
import static java.lang.Math.min;

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

int localIconSize = iconSize == 0 ? icon.getIntrinsicHeight() : iconSize;
int newIconTop =
(buttonHeight
- getTextHeight()
- getPaddingTop()
- localIconSize
- iconPadding
- getPaddingBottom())
/ 2;
max(
0, // Always put the icon on top if the content height is taller than the button.
(buttonHeight
- getTextHeight()
- getPaddingTop()
- localIconSize
- iconPadding
- getPaddingBottom())
/ 2);

if (iconTop != newIconTop) {
iconTop = newIconTop;
Expand All @@ -617,10 +621,14 @@ private int getTextWidth() {
buttonText = getTransformationMethod().getTransformation(buttonText, this).toString();
}

return Math.min((int) textPaint.measureText(buttonText), getLayout().getEllipsizedWidth());
return min((int) textPaint.measureText(buttonText), getLayout().getEllipsizedWidth());
}

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

return Math.min(bounds.height(), getLayout().getHeight());
return min(bounds.height(), getLayout().getHeight());
}

private boolean isLayoutRTL() {
Expand Down

0 comments on commit 19d0500

Please sign in to comment.