How to make error message in TextInputLayout appear in center
Asked Answered
F

7

8

Currently it looks as in attached with this layout:

<android.support.design.widget.TextInputLayout
    android:id="@+id/layoutCurrentPW"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    app:errorEnabled="true">

How to set the error message "password must at least be 8 characters" to center gravity ?
I tried with android:gravity="center" but that did not work.

enter image description here

EDIT
Layout that includes EditText:

<android.support.design.widget.TextInputLayout
    android:id="@+id/layoutCurrentPW"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    app:errorEnabled="true">

        <EditText
            android:id="@+id/editTextCurrentPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:layout_marginLeft="50dp"
            android:layout_marginRight="50dp"
            android:gravity="center"
            android:hint="@string/current_password"
            android:inputType="textPassword"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="@color/black" />
    </android.support.design.widget.TextInputLayout>
Fistulous answered 30/11, 2015 at 12:16 Comment(2)
Review this: Material EditText.Shedd
Maybe this can be achieved with a style, simliar to thisMohandis
F
6

I wanted to know if there is any way to handle it from framework..seems no.

But the way TextInputLayout work is:
- hint will be shown on top of EditText when user touches it.
- Error messages will be shown just under the TextInputLayout and aligned to start.

I had 40dp of left_margin to my EditText due to which misalignment between hint and error message. So for now, I removed left_margin 40dp from EditText and applied same to TextInputLayout itself so it looks fine now.

Lesson learnt :-) is if any margins has to be applied to EditText, better same, if possible, can be applied to TextInputLayout to keep hint and error messages to be placed properly.

Fistulous answered 30/11, 2015 at 13:11 Comment(0)
W
3
class CenterErrorTextInputLayout(context: Context, attrs: AttributeSet) : TextInputLayout(context, attrs) {
override fun setErrorTextAppearance(resId: Int) {
    super.setErrorTextAppearance(resId)
    val errorTextView = this.findViewById<TextView>(R.id.textinput_error)
    val errorFrameLayout = errorTextView.parent as FrameLayout

    errorTextView.gravity = Gravity.CENTER
    errorFrameLayout.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
}}
Wag answered 2/8, 2018 at 6:55 Comment(2)
Copy Paste FTW?Jetport
For those who didn't have the same issue as OP, but actually needed to center error message with normal margins, this actually works pretty wellMelinite
F
1

Here a solution that always centers the errormessage no matter how big your TextInputLayout is.

You make a own class that inherits from TextInputLayout. Then override the ShowError(string text, Drawable icon) method. If the error is called you center the textView with the error.

    public class TextInputLayout_Center : TextInputLayout
    {
        public override void ShowError(string text, Android.Graphics.Drawables.Drawable icon)
        {
            base.ShowError(text, icon);

            centerErrorMessage(this);
        }

        void centerErrorMessage(ViewGroup view)
        {
            for (int i = 0; i < view.ChildCount; i++)
            {
                View v = view.GetChildAt(i);
                if (v.GetType() == typeof(TextView))
                {
                    v.LayoutParameters = new LayoutParams(ViewGroup.LayoutParams.MatchParent, v.LayoutParameters.Height);
                    ((TextView)v).Gravity = GravityFlags.CenterHorizontal;
                    ((TextView)v).TextAlignment = TextAlignment.Center;
                }
                if (v is ViewGroup)
                {
                    centerErrorMessage((ViewGroup)v);
                }
            }
        }
    }
Fielder answered 3/1, 2017 at 13:0 Comment(1)
Yes, this code is written in c# for Xamarin, but is basically the same. @CharlesMadereFielder
V
1

I achieved it by setting start margin for the error view. Below you can see my overriden version of setError method of the TextInputLayout component.

@Override
public void setError(@Nullable CharSequence errorText) {
    // allow android component to create error view
    if (errorText == null) {
        return;
    }
    super.setError(errorText);
    // find this error view and calculate start margin to make it look like centered
    final TextView errorTextInput = (TextView) findViewById(R.id.textinput_error);
    errorTextInput.measure(0, 0);
    int errorWidth = errorTextInput.getMeasuredWidth();
    int layoutWidth = getWidth();
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) errorTextInput.getLayoutParams();
    params.setMarginStart((layoutWidth - errorWidth) / 2);
    errorTextInput.setLayoutParams(params);
}
Viscometer answered 19/6, 2017 at 8:47 Comment(0)
P
0
@Override
public void setErrorEnabled(boolean enabled) {
    super.setErrorEnabled(enabled);
    if (!enabled)
        return;
    try {
        setErrorGravity(this);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void setErrorGravity(ViewGroup view) throws Exception {
    for (int i = 0; i < view.getChildCount(); i++) {
        View errorView = view.getChildAt(i);
        if (errorView instanceof TextView) {
            if (errorView.getId() == com.google.android.material.R.id.textinput_error) {
                FrameLayout errorViewParent = (FrameLayout) errorView.getParent();
                errorViewParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                ((TextView) errorView).setGravity(Gravity.RIGHT);
                ((TextView) errorView).setTypeface(FontUtils.getTypeFace(view.getContext(), FontUtils.FONT_NAZANIN_TAR));
            }
        }
        if (errorView instanceof ViewGroup) {
            setErrorGravity((ViewGroup) errorView);
        }
    }
}
Pedlar answered 5/11, 2019 at 10:36 Comment(0)
M
0

Hi if you using last version of material design (v 1.2 and above), you have to use this way: (I set gravity to end for support rtl) Thanks @Emmanuel Guerra

class MyTextInputLayout : TextInputLayout {

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttrs: Int) : super(context, attrs, defStyleAttrs)

    override fun setErrorEnabled(enabled: Boolean) {
        super.setErrorEnabled(enabled)
        if (!enabled) {
            return
        }
        try {
            changeTextAlignment(com.google.android.material.R.id.textinput_error, View.TEXT_ALIGNMENT_VIEW_END)
            val errorView: ViewGroup = this.getChildAt(1) as LinearLayout

            val params: LinearLayout.LayoutParams = errorView.layoutParams as LinearLayout.LayoutParams

            params.gravity = Gravity.END

            errorView.layoutParams = params
            //errorView.setPadding(0, 0, 0, 0) //use this to remove error text padding
            //setErrorIconDrawable(0)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


    private fun changeTextAlignment(textViewId: Int, alignment: Int) {
        val textView = findViewById<TextView>(textViewId)
        textView.textAlignment = alignment
    }
}
Mccloud answered 1/2, 2021 at 11:26 Comment(0)
D
0

A custom TextInputLayout class for for aligning the error text.

class CenterErrorTextInputLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0

) : TextInputLayout(context, attrs, defStyleAttr) {

    override fun setErrorEnabled(enabled: Boolean) {
        super.setErrorEnabled(enabled)

        if (!enabled) return

        try {
            setErrorTextAlignment()
        } catch (e: Exception) {
            Timber.e(e, "Failed to set error text :    RightErrorTextInputLayout")
        }
    }

    private fun setErrorTextAlignment() {
        val errorView: TextView = this.findViewById(R.id.textinput_error)
        errorView.textAlignment = View.TEXT_ALIGNMENT_CENTER
    }
}

To align the text to the end, use View.TEXT_ALIGNMENT_VIEW_END instead.

Dice answered 6/11, 2021 at 2:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.