Design Android EditText to show error message as described by google
There's no need to use a third-party library since Google introduced the TextInputLayout
as part of the design-support-library
.
Following a basic example:
Layout
<android.support.design.widget.TextInputLayout
android:id="@+id/text_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<android.support.design.widget.TextInputEditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter your name" />
</android.support.design.widget.TextInputLayout>
Note: By setting app:errorEnabled="true"
as an attribute of the TextInputLayout
it won't change it's size once an error is displayed - so it basically blocks the space.
Code
In order to show the Error below the EditText
you simply need to call #setError
on the TextInputLayout
(NOT on the child EditText
):
TextInputLayout til = (TextInputLayout) findViewById(R.id.text_input_layout);
til.setError("You need to enter a name");
Result
To hide the error and reset the tint simply call til.setError(null)
.
Note
In order to use the TextInputLayout
you have to add the following to your build.gradle
dependencies:
dependencies {
compile 'com.android.support:design:25.1.0'
}
Setting a custom color
By default the line of the EditText
will be red. If you need to display a different color you can use the following code as soon as you call setError
.
editText.getBackground().setColorFilter(getResources().getColor(R.color.red_500_primary), PorterDuff.Mode.SRC_ATOP);
To clear it simply call the clearColorFilter
function, like this:
editText.getBackground().clearColorFilter();
How to show EditText error below the layout instead of a popup?
Set error on TextInputLayout
instead of TextInputEditText
so try this :
password_layout_signup_page.setError("Be at least 8 characters")
Design Android EditText to show error message on floating label hint
Please try this one bro
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.exa);
inputLayoutEmail = (TextInputLayout) findViewById(R.id.input_layout_email);
inputLayoutPassword = (TextInputLayout) findViewById(R.id.input_layout_password);
inputEmail = (EditText) findViewById(R.id.input_email);
inputPassword = (EditText) findViewById(R.id.input_password);
btnSignUp = (Button) findViewById(R.id.btn_signup);
inputEmail.addTextChangedListener(new MyTextWatcher(inputEmail));
inputPassword.addTextChangedListener(new MyTextWatcher(inputPassword));
btnSignUp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
submitForm();
}
});
}
private void submitForm() {
if (!validateEmail()) {
return;
}
if (!validatePassword()) {
return;
}
Toast.makeText(getApplicationContext(), "Thank You!", Toast.LENGTH_SHORT).show();
}
private boolean validateEmail() {
String email = inputEmail.getText().toString().trim();
if (email.isEmpty() || !isValidEmail(email)) {
inputLayoutEmail.setHint(getString(R.string.err_msg_email));
requestFocus(inputEmail);
return false;
} else {
inputLayoutEmail.setErrorEnabled(false);
inputLayoutEmail.setHint("Email");
}
return true;
}
private boolean validatePassword() {
if (inputPassword.getText().toString().trim().isEmpty()) {
inputLayoutPassword.setHint(getString(R.string.err_msg_password));
requestFocus(inputPassword);
return false;
} else {
inputLayoutPassword.setErrorEnabled(false);
inputLayoutPassword.setHint("Password");
}
return true;
}
private static boolean isValidEmail(String email) {
return !TextUtils.isEmpty(email) && android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches();
}
private void requestFocus(View view) {
if (view.requestFocus()) {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
}
private class MyTextWatcher implements TextWatcher {
private View view;
private MyTextWatcher(View view) {
this.view = view;
}
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
public void afterTextChanged(Editable editable) {
switch (view.getId()) {
case R.id.input_email:
validateEmail();
break;
case R.id.input_password:
validatePassword();
break;
}
}
}
How to make error message in TextInputLayout appear in center
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.
Android EditText error message popup text not showing
You need to use style="@style/AppTheme.WhiteEditText"
Instead of android:theme="@style/AppTheme.WhiteColorAccent"
Now question is why need to use
style
Instead ofandroid:theme
When you use style
it apply will apply only to that view
and When you use android:theme
it apply will apply view
as well as all of its children
.
Read more about What is the difference between style and android:theme attributes?
SAMPLE CODE
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:layout_height="match_parent"
android:background="@color/colorPrimary">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:visibility="gone" />
<ProgressBar
android:id="@+id/login_progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:visibility="gone" />
<ScrollView
android:id="@+id/form"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
android:fillViewport="true">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="80dp"
android:orientation="vertical">
<android.support.constraint.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:layout_marginBottom="20dp">
<ImageView
android:id="@+id/profileImageView"
android:layout_width="160dp"
android:layout_height="160dp"
android:scaleType="fitXY"
android:src="@color/colorNavBar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/cameraImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:srcCompat="@android:drawable/ic_menu_camera" />
</android.support.constraint.ConstraintLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/firstnameTvLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="20dp"
android:layout_weight="0.33"
android:textColorHint="@color/colorVeryLightGray"
style="@style/AppTheme.WhiteColorAccent"
>
<android.support.design.widget.TextInputEditText
android:id="@+id/firstnameTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="First Name"
android:inputType="textPersonName"
android:maxLines="1"
android:imeOptions="actionNext"
android:nextFocusDown="@id/lastnameTv"
android:nextFocusForward="@id/lastnameTv"
android:textColor="@android:color/white"
android:textColorHint="@color/colorWhite"
style="@style/AppTheme.WhiteEditText" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/lastnameTvLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="20dp"
android:layout_weight="0.33"
android:textColorHint="@color/colorVeryLightGray"
style="@style/AppTheme.WhiteColorAccent">
<android.support.design.widget.TextInputEditText
android:id="@+id/lastnameTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Last Name"
android:inputType="textPersonName"
android:maxLines="1"
android:nextFocusDown="@id/usernameTv"
android:nextFocusForward="@id/usernameTv"
android:singleLine="true"
android:textColor="@android:color/white"
android:textColorHint="@color/colorWhite"
style="@style/AppTheme.WhiteEditText" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/usernameTvLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="20dp"
android:layout_weight="0.33"
android:textColorHint="@color/colorVeryLightGray"
style="@style/AppTheme.WhiteColorAccent">
<android.support.design.widget.TextInputEditText
android:id="@+id/usernameTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="user Name"
android:imeActionId="6"
android:imeActionLabel="AB"
android:imeOptions="actionUnspecified"
android:maxLines="1"
android:nextFocusDown="@id/nextBtn"
android:nextFocusForward="@id/nextBtn"
android:singleLine="true"
android:textColor="@android:color/white"
android:textColorHint="@color/colorWhite"
style="@style/AppTheme.WhiteEditText" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
<Button
android:id="@+id/nextBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:layout_marginTop="16dp"
android:text="Next"
android:textStyle="bold"
app:layout_anchor="@+id/form"
app:layout_anchorGravity="bottom|center_horizontal" />
</android.support.design.widget.CoordinatorLayout>
style
<style name="AppTheme.WhiteColorAccent">
<item name="colorAccent">@color/colorWhite</item>
</style>
<style name="AppTheme.WhiteEditText" parent="Widget.AppCompat.EditText">
<item name="android:textColor">@color/colorWhite</item>
<item name="colorControlNormal">@color/colorVeryLightGray</item>
<item name="colorControlActivated">@color/colorWhite</item>
<item name="colorControlHighlight">@color/colorWhite</item>
</style>
OUTPUT
How to write style to error text of EditText in android?
The solution is at the end and here is the screenshot:
Some Explanation
You might be able to set the textcolor using the following line
yourEditText.setError(Html.fromHtml("<font color='blue'>this is the error</font>"));
However, this might not be guaranteed.
According to the source code, this Popup
that shows is of type ErrorPopup
which is an internal class inside TextView
. The content of this Popup
is a single TextView
inflated from com.android.internal.R.layout.textview_hint
final TextView err = (TextView) inflater.inflate(com.android.internal.R.layout.textview_hint,
null);
The background of this Popup
depends on whether it should be placed above the anchor:
if (above) {
mView.setBackgroundResource(com.android.internal.R.drawable.popup_inline_error_above);
} else {
mView.setBackgroundResource(com.android.internal.R.drawable.popup_inline_error);
}
Since all the android resources used to create the popup are internal and ultimately hard-coded, your best shot would be to create your own error popup. This would be very easy and you wouldn't really be interfering with the normal EditText
because the default popup is merely used to show the error, and, thus, creating your own would be fine.
SOLUTION
I have created it here: WidgyWidgets
EditText.setError doesnt show Error text and only shows icon
Use TextInputLayout
for material EditText
like :
<android.support.design.widget.TextInputLayout
android:id="@+id/input_application_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:minHeight="50dp"
android:theme="@style/MyTextInputLayout"
app:hintTextAppearance="@style/TextAppearance.App.TextInputLayout">
<EditText
android:id="@+id/application_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_application_name"
android:imeOptions="actionNext"
android:inputType="text" />
</android.support.design.widget.TextInputLayout>
and in your Activity
TextInputLayout til = (TextInputLayout) findViewById(R.id.input_application_name);
EditText applicationNameEdt = (EditText) findViewById(R.id.application_name);
til.setErrorEnabled(true);
til.setError("You need to enter a name");
Related Topics
Why Does Contentresolver.Requestsync Not Trigger a Sync
How to Fix: "Hax Is Not Working and Emulator Runs in Emulation Mode"
Handle Screen Rotation Without Losing Data - Android
Creating an Android Trial Application That Expires After a Fixed Time Period
How to Start Service-Only Android App
Jetpack Compose - Order of Modifiers
Get Bitmap Attached to Imageview
How Permission Can Be Checked at Runtime Without Throwing Securityexception
How to Save a Bitmap on Internal Storage
"Parse Error: There Is a Problem Parsing the Package" While Installing Android Application
How to Create a Table with Borders in Android
Hide/Show Bottomnavigationview on Scroll
How to Create Edittext Accepts Alphabets Only in Android
Create Blurry Transparent Background Effect