From b6b895a1e40efbf2e36b2ea5e91bae7bcd0bdb8c Mon Sep 17 00:00:00 2001 From: conradchen Date: Mon, 11 Apr 2022 16:33:02 -0400 Subject: [PATCH] [Button] Fix icon textStart/End alignment with multiline text When calculating text width to decide the icon position with textStart/End alignment, we missed accounting for multiline text. Fixes this by calculating each line's width separately and take the widest one to decide the icon position. Resolves https://github.com/material-components/material-components-android/issues/2007 PiperOrigin-RevId: 440982189 --- .../material/button/MaterialButton.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/java/com/google/android/material/button/MaterialButton.java b/lib/java/com/google/android/material/button/MaterialButton.java index f10b0d1d6a5..962c76b33e6 100644 --- a/lib/java/com/google/android/material/button/MaterialButton.java +++ b/lib/java/com/google/android/material/button/MaterialButton.java @@ -568,7 +568,7 @@ private void updateIconPosition(int buttonWidth, int buttonHeight) { int localIconSize = iconSize == 0 ? icon.getIntrinsicWidth() : iconSize; int availableWidth = buttonWidth - - getTextWidth() + - getTextLayoutWidth() - ViewCompat.getPaddingEnd(this) - localIconSize - iconPadding @@ -612,9 +612,18 @@ private void updateIconPosition(int buttonWidth, int buttonHeight) { } } - private int getTextWidth() { + private int getTextLayoutWidth() { + int maxWidth = 0; + int lineCount = getLineCount(); + for (int line = 0; line < lineCount; line++) { + maxWidth = max(maxWidth, getTextWidth(getTextInLine(line))); + } + return maxWidth; + } + + private int getTextWidth(CharSequence text) { Paint textPaint = getPaint(); - String buttonText = getText().toString(); + String buttonText = text.toString(); if (getTransformationMethod() != null) { // if text is transformed, add that transformation to to ensure correct calculation // of icon padding. @@ -643,6 +652,12 @@ private int getTextHeight() { return min(bounds.height(), getLayout().getHeight()); } + private CharSequence getTextInLine(int line) { + int start = getLayout().getLineStart(line); + int end = getLayout().getLineEnd(line); + return getText().subSequence(start, end); + } + private boolean isLayoutRTL() { return ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL; }