From 7d46b95e9e183907c12dc86f065a13b6ad6bf7f0 Mon Sep 17 00:00:00 2001 From: pfthomas Date: Thu, 20 Jan 2022 14:37:23 -0500 Subject: [PATCH] [TextInputLayout] Add support for minEms and maxEms Resolves https://github.com/material-components/material-components-android/issues/2269 PiperOrigin-RevId: 423118234 --- docs/components/TextField.md | 6 +- .../material/textfield/TextInputLayout.java | 74 +++++++++++++++++-- .../material/textfield/res/values/attrs.xml | 14 +++- 3 files changed, 82 insertions(+), 12 deletions(-) diff --git a/docs/components/TextField.md b/docs/components/TextField.md index 3f0ca04f118..825e02ccc15 100644 --- a/docs/components/TextField.md +++ b/docs/components/TextField.md @@ -319,9 +319,9 @@ The recommended default `android:layout_width` is `245dp`. By default, text fields have a maximum width of `488dp`, and a minimum width of `56dp` for layouts without a label. If a label is present, the minimum width -recommended is `88dp`. `android:minWidth` and `android:maxWidth` should be set -on the `TextInputLayout` instead of on the `TextInputEditText` to avoid -unintended behaviors. +recommended is `88dp`. `android:minWidth` and `android:maxWidth` (as well as +`android:minEms` and `android:maxEms`) should be set on the `TextInputLayout` +instead of on the `TextInputEditText` to avoid unintended behaviors. You can override those values in a custom style that inherits from a `TextInputLayout` style or by making changes directly on the layout: diff --git a/lib/java/com/google/android/material/textfield/TextInputLayout.java b/lib/java/com/google/android/material/textfield/TextInputLayout.java index 6090337ba84..a42ae1c1b36 100644 --- a/lib/java/com/google/android/material/textfield/TextInputLayout.java +++ b/lib/java/com/google/android/material/textfield/TextInputLayout.java @@ -200,6 +200,8 @@ public class TextInputLayout extends LinearLayout { EditText editText; private CharSequence originalHint; + private int minEms = NO_WIDTH; + private int maxEms = NO_WIDTH; private int minWidth = NO_WIDTH; private int maxWidth = NO_WIDTH; @@ -507,10 +509,14 @@ public TextInputLayout(@NonNull Context context, @Nullable AttributeSet attrs, i hintAnimationEnabled = a.getBoolean(R.styleable.TextInputLayout_hintAnimationEnabled, true); expandedHintEnabled = a.getBoolean(R.styleable.TextInputLayout_expandedHintEnabled, true); - if (a.hasValue(R.styleable.TextInputLayout_android_minWidth)) { + if (a.hasValue(R.styleable.TextInputLayout_android_minEms)) { + setMinEms(a.getInt(R.styleable.TextInputLayout_android_minEms, NO_WIDTH)); + } else if (a.hasValue(R.styleable.TextInputLayout_android_minWidth)) { setMinWidth(a.getDimensionPixelSize(R.styleable.TextInputLayout_android_minWidth, NO_WIDTH)); } - if (a.hasValue(R.styleable.TextInputLayout_android_maxWidth)) { + if (a.hasValue(R.styleable.TextInputLayout_android_maxEms)) { + setMaxEms(a.getInt(R.styleable.TextInputLayout_android_maxEms, NO_WIDTH)); + } else if (a.hasValue(R.styleable.TextInputLayout_android_maxWidth)) { setMaxWidth(a.getDimensionPixelSize(R.styleable.TextInputLayout_android_maxWidth, NO_WIDTH)); } @@ -1458,8 +1464,16 @@ private void setEditText(EditText editText) { } this.editText = editText; - setMinWidth(minWidth); - setMaxWidth(maxWidth); + if (minEms != NO_WIDTH) { + setMinEms(minEms); + } else { + setMinWidth(minWidth); + } + if (maxEms != NO_WIDTH) { + setMaxEms(maxEms); + } else { + setMaxWidth(maxWidth); + } onApplyBoxBackgroundMode(); setTextInputAccessibilityDelegate(new AccessibilityDelegate(this)); @@ -1613,6 +1627,56 @@ public EditText getEditText() { return editText; } + /** + * Sets the minimum width in terms of ems of the text field. The layout will be at least + * {@code minEms} wide if its {@code layout_width} is set to {@code wrap_content}. + * + * @param minEms The minimum width in terms of ems to be set + * @attr ref com.google.android.material.R.styleable#TextInputLayout_android_minEms + * @see #getMinEms() + */ + public void setMinEms(int minEms) { + this.minEms = minEms; + if (editText != null && minEms != NO_WIDTH) { + editText.setMinEms(minEms); + } + } + + /** + * Returns the text field's minimum width in terms of ems, or -1 if no minimum width is set. + * + * @attr ref com.google.android.material.R.styleable#TextInputLayout_android_minEms + * @see #setMinEms(int) + */ + public int getMinEms() { + return minEms; + } + + /** + * Sets the maximum width in terms of ems of the text field. The layout will be at most + * {@code maxEms} wide if its {@code layout_width} is set to {@code wrap_content}. + * + * @param maxEms The maximum width in terms of ems to be set + * @attr ref com.google.android.material.R.styleable#TextInputLayout_android_maxEms + * @see #getMaxEms() + */ + public void setMaxEms(int maxEms) { + this.maxEms = maxEms; + if (editText != null && maxEms != NO_WIDTH) { + editText.setMaxEms(maxEms); + } + } + + /** + * Returns the text field's maximum width in terms of ems, or -1 if no maximum width is set. + * + * @attr ref com.google.android.material.R.styleable#TextInputLayout_android_maxEms + * @see #setMaxEms(int) + */ + public int getMaxEms() { + return maxEms; + } + /** * Sets the minimum width of the text field. The layout will be at least this dimension wide if * its {@code layout_width} is set to {@code wrap_content}. @@ -1688,7 +1752,7 @@ public void setMaxWidthResource(@DimenRes int maxWidthId) { * * @attr ref com.google.android.material.R.styleable#TextInputLayout_android_maxWidth * @see #setMaxWidth(int) - * @see #setMaxWidthResource(int) (int) + * @see #setMaxWidthResource(int) */ @Px public int getMaxWidth() { diff --git a/lib/java/com/google/android/material/textfield/res/values/attrs.xml b/lib/java/com/google/android/material/textfield/res/values/attrs.xml index a5bf2e83d28..ae5020e736a 100644 --- a/lib/java/com/google/android/material/textfield/res/values/attrs.xml +++ b/lib/java/com/google/android/material/textfield/res/values/attrs.xml @@ -45,11 +45,17 @@ - + + + + - + @@ -238,7 +244,7 @@ + and disabled states. -->