From d9b97b42ffa46bc41fc54b194ae4c59eb8fcf818 Mon Sep 17 00:00:00 2001 From: conradchen Date: Tue, 21 Feb 2023 21:29:44 -0800 Subject: [PATCH] [TextField] Make collapsed hint aligned with prefix and suffix text The original logic prevents displaying the collapsed hint on top of suffix text. The behavior looks not consistent with the case of prefix text or outline variants of text fields. This CL also fixes the issue that when drawable paddings are set on EditText, the collapsed hint is not aligned with the prefix anymore. Resolves https://github.com/material-components/material-components-android/issues/2800 PiperOrigin-RevId: 511390069 --- .../material/textfield/EndCompoundLayout.java | 15 ++++++++ .../textfield/StartCompoundLayout.java | 15 ++++++++ .../material/textfield/TextInputLayout.java | 34 ++++++++++--------- 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/lib/java/com/google/android/material/textfield/EndCompoundLayout.java b/lib/java/com/google/android/material/textfield/EndCompoundLayout.java index fb119d70c44..7465f87e3b1 100644 --- a/lib/java/com/google/android/material/textfield/EndCompoundLayout.java +++ b/lib/java/com/google/android/material/textfield/EndCompoundLayout.java @@ -737,6 +737,21 @@ void updateSuffixTextViewPadding() { textInputLayout.editText.getPaddingBottom()); } + int getSuffixTextEndOffset() { + int endIconOffset; + if (isEndIconVisible() || isErrorIconVisible()) { + endIconOffset = + endIconView.getMeasuredWidth() + + MarginLayoutParamsCompat.getMarginStart( + (MarginLayoutParams) endIconView.getLayoutParams()); + } else { + endIconOffset = 0; + } + return ViewCompat.getPaddingEnd(this) + + ViewCompat.getPaddingEnd(suffixTextView) + + endIconOffset; + } + @Nullable CheckableImageButton getCurrentEndIconView() { if (isErrorIconVisible()) { diff --git a/lib/java/com/google/android/material/textfield/StartCompoundLayout.java b/lib/java/com/google/android/material/textfield/StartCompoundLayout.java index ebf84555194..61f0df19299 100644 --- a/lib/java/com/google/android/material/textfield/StartCompoundLayout.java +++ b/lib/java/com/google/android/material/textfield/StartCompoundLayout.java @@ -328,6 +328,21 @@ void updatePrefixTextViewPadding() { editText.getCompoundPaddingBottom()); } + int getPrefixTextStartOffset() { + int startIconOffset; + if (isStartIconVisible()) { + startIconOffset = + startIconView.getMeasuredWidth() + + MarginLayoutParamsCompat.getMarginEnd( + (MarginLayoutParams) startIconView.getLayoutParams()); + } else { + startIconOffset = 0; + } + return ViewCompat.getPaddingStart(this) + + ViewCompat.getPaddingStart(prefixTextView) + + startIconOffset; + } + void onHintStateChanged(boolean hintExpanded) { this.hintExpanded = hintExpanded; updateVisibility(); diff --git a/lib/java/com/google/android/material/textfield/TextInputLayout.java b/lib/java/com/google/android/material/textfield/TextInputLayout.java index 5ef2d0cee7a..69370495ba2 100644 --- a/lib/java/com/google/android/material/textfield/TextInputLayout.java +++ b/lib/java/com/google/android/material/textfield/TextInputLayout.java @@ -2769,35 +2769,37 @@ private Rect calculateCollapsedTextBounds(@NonNull Rect rect) { bounds.right = rect.right - editText.getPaddingRight(); return bounds; case BOX_BACKGROUND_FILLED: - bounds.left = getLabelLeftBoundAlightWithPrefix(rect.left, isRtl); + bounds.left = getLabelLeftBoundAlignedWithPrefixAndSuffix(rect.left, isRtl); bounds.top = rect.top + boxCollapsedPaddingTopPx; - bounds.right = getLabelRightBoundAlignedWithSuffix(rect.right, isRtl); + bounds.right = getLabelRightBoundAlignedWithPrefixAndSuffix(rect.right, isRtl); return bounds; case BOX_BACKGROUND_NONE: default: - bounds.left = getLabelLeftBoundAlightWithPrefix(rect.left, isRtl); + bounds.left = getLabelLeftBoundAlignedWithPrefixAndSuffix(rect.left, isRtl); bounds.top = getPaddingTop(); - bounds.right = getLabelRightBoundAlignedWithSuffix(rect.right, isRtl); + bounds.right = getLabelRightBoundAlignedWithPrefixAndSuffix(rect.right, isRtl); return bounds; } } - private int getLabelLeftBoundAlightWithPrefix(int rectLeft, boolean isRtl) { - int left = rectLeft + editText.getCompoundPaddingLeft(); - if (getPrefixText() != null && !isRtl) { - // Label should be vertically aligned with prefix - left = left - getPrefixTextView().getMeasuredWidth() + getPrefixTextView().getPaddingLeft(); + private int getLabelLeftBoundAlignedWithPrefixAndSuffix(int rectLeft, boolean isRtl) { + if (!isRtl && getPrefixText() != null) { + return rectLeft + startLayout.getPrefixTextStartOffset(); } - return left; + if (isRtl && getSuffixText() != null) { + return rectLeft + endLayout.getSuffixTextEndOffset(); + } + return rectLeft + editText.getCompoundPaddingLeft(); } - private int getLabelRightBoundAlignedWithSuffix(int rectRight, boolean isRtl) { - int right = rectRight - editText.getCompoundPaddingRight(); - if (getPrefixText() != null && isRtl) { - // Label should be vertically aligned with prefix if in RTL - right += getPrefixTextView().getMeasuredWidth() - getPrefixTextView().getPaddingRight(); + private int getLabelRightBoundAlignedWithPrefixAndSuffix(int rectRight, boolean isRtl) { + if (!isRtl && getSuffixText() != null) { + return rectRight - endLayout.getSuffixTextEndOffset(); + } + if (isRtl && getPrefixText() != null) { + return rectRight - startLayout.getPrefixTextStartOffset(); } - return right; + return rectRight - editText.getCompoundPaddingRight(); } @NonNull