diff --git a/docs/components/TextField.md b/docs/components/TextField.md index b5c24b94d..a9c78d952 100644 --- a/docs/components/TextField.md +++ b/docs/components/TextField.md @@ -312,11 +312,36 @@ _**Note:** Non-null error text will replace any existing helper text._ ### Text field dimensions -By default, text fields have a maximum width of `488dp`, and a minimum with of -`56dp` for layouts without a label. If a label is present, the minimum width -recommended is of `88dp`. +The recommended default `android:layout_width` is `245dp`. -The recommended default `android:layout_width` is of `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. + +You can override those values in a custom style that inherits from a +`TextInputLayout` style or directly on the layout: + +```xml + + + + + +``` + +_**Note:** The `android:layout_width` of the `TextInputLayout` should be +`wrap_content` in order for those minimum and maximum dimensions to be used._ ### Using text fields programmatically diff --git a/lib/java/com/google/android/material/textfield/TextInputLayout.java b/lib/java/com/google/android/material/textfield/TextInputLayout.java index 8c0cc4c4c..755655f63 100644 --- a/lib/java/com/google/android/material/textfield/TextInputLayout.java +++ b/lib/java/com/google/android/material/textfield/TextInputLayout.java @@ -73,6 +73,7 @@ import androidx.annotation.DrawableRes; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.Px; import androidx.annotation.RestrictTo; import androidx.annotation.StringRes; import androidx.annotation.StyleRes; @@ -183,6 +184,7 @@ public class TextInputLayout extends LinearLayout { private static final int LABEL_SCALE_ANIMATION_DURATION = 167; private static final int INVALID_MAX_LENGTH = -1; + private static final int NO_WIDTH = -1; private static final String LOG_TAG = "TextInputLayout"; @@ -193,6 +195,9 @@ public class TextInputLayout extends LinearLayout { EditText editText; private CharSequence originalHint; + private int minWidth = NO_WIDTH; + private int maxWidth = NO_WIDTH; + private final IndicatorViewController indicatorViewController = new IndicatorViewController(this); boolean counterEnabled; @@ -478,6 +483,13 @@ public class TextInputLayout extends LinearLayout { hintAnimationEnabled = a.getBoolean(R.styleable.TextInputLayout_hintAnimationEnabled, true); expandedHintEnabled = a.getBoolean(R.styleable.TextInputLayout_expandedHintEnabled, true); + 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)) { + setMaxWidth(a.getDimensionPixelSize(R.styleable.TextInputLayout_android_maxWidth, NO_WIDTH)); + } + shapeAppearanceModel = ShapeAppearanceModel.builder(context, attrs, defStyleAttr, DEF_STYLE_RES).build(); @@ -1388,6 +1400,8 @@ public class TextInputLayout extends LinearLayout { } this.editText = editText; + setMinWidth(minWidth); + setMaxWidth(maxWidth); onApplyBoxBackgroundMode(); setTextInputAccessibilityDelegate(new AccessibilityDelegate(this)); @@ -1538,6 +1552,88 @@ public class TextInputLayout extends LinearLayout { return editText; } + /** + * 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}. + * + * @param minWidth The minimum width to be set + * @attr ref com.google.android.material.R.styleable#TextInputLayout_android_minWidth + * @see #setMinWidthResource(int) + * @see #getMinWidth() + */ + public void setMinWidth(@Px int minWidth) { + this.minWidth = minWidth; + if (editText != null && minWidth != NO_WIDTH) { + editText.setMinWidth(minWidth); + } + } + + /** + * 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}. + * + * @param minWidthId The id of the minimum width dimension resource to be set + * @attr ref com.google.android.material.R.styleable#TextInputLayout_android_minWidth + * @see #setMinWidth(int) + * @see #getMinWidth() + */ + public void setMinWidthResource(@DimenRes int minWidthId) { + setMinWidth(getContext().getResources().getDimensionPixelSize(minWidthId)); + } + + /** + * Returns the text field's minimum width, or -1 if no minimum width is set. + * + * @attr ref com.google.android.material.R.styleable#TextInputLayout_android_minWidth + * @see #setMinWidth(int) + * @see #setMinWidthResource(int) (int) + */ + @Px + public int getMinWidth() { + return minWidth; + } + + /** + * Sets the maximum width of the text field. The layout will be at most this dimension wide if + * its {@code layout_width} is set to {@code wrap_content}. + * + * @param maxWidth The maximum width to be set + * @attr ref com.google.android.material.R.styleable#TextInputLayout_android_maxWidth + * @see #setMaxWidthResource(int) + * @see #getMaxWidth() + */ + public void setMaxWidth(@Px int maxWidth) { + this.maxWidth = maxWidth; + if (editText != null && maxWidth != NO_WIDTH) { + editText.setMaxWidth(maxWidth); + } + } + + /** + * Sets the maximum width of the text field. The layout will be at most this dimension wide if + * its {@code layout_width} is set to {@code wrap_content}. + * + * @param maxWidthId The id of the maximum width dimension resource to be set + * @attr ref com.google.android.material.R.styleable#TextInputLayout_android_maxWidth + * @see #setMaxWidth(int) + * @see #getMaxWidth() + */ + public void setMaxWidthResource(@DimenRes int maxWidthId) { + setMaxWidth(getContext().getResources().getDimensionPixelSize(maxWidthId)); + } + + /** + * Returns the text field's maximum width, or -1 if no maximum width is set. + * + * @attr ref com.google.android.material.R.styleable#TextInputLayout_android_maxWidth + * @see #setMaxWidth(int) + * @see #setMaxWidthResource(int) (int) + */ + @Px + public int getMaxWidth() { + return maxWidth; + } + /** * Set the hint to be displayed in the floating label, if enabled. * 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 20f42b1ac..82f5a6e98 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 @@ -27,6 +27,12 @@ + + + + diff --git a/lib/java/com/google/android/material/textfield/res/values/styles.xml b/lib/java/com/google/android/material/textfield/res/values/styles.xml index 1b7e2683e..ef02320de 100644 --- a/lib/java/com/google/android/material/textfield/res/values/styles.xml +++ b/lib/java/com/google/android/material/textfield/res/values/styles.xml @@ -58,7 +58,7 @@ true @dimen/material_textinput_min_width - @dimen/material_textinput_min_width + @dimen/material_textinput_max_width outline @null @drawable/mtrl_ic_error