1

I have a form where the user enter the client info. When I try to validate the fields I have a problem, I used editText.setError(errorMessage) and it's showing the error message, but it shown on the top of my EditText making it confusing to the user. Like the image below.

enter image description here

Any ideas of how I can fix this?

EditText on XML

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="br.com.intelecto.intesigmobile.activity.ClienteEditActivityFragment">

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:id="@+id/et_nome"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/cliente_nome"
        android:imeActionId="@+id/cli_name"
        android:imeActionLabel="@string/str_next"
        android:imeOptions="actionUnspecified"
        android:inputType="textPersonName"
        android:maxLines="1"
        android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:id="@+id/et_telefone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/cliente_telefone"
        android:imeActionId="@+id/cli_cpf"
        android:imeActionLabel="@string/str_next"
        android:imeOptions="actionUnspecified"
        android:inputType="phone"
        android:maxLines="1"
        android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:id="@+id/et_email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/cliente_email"
        android:imeActionId="@+id/cli_cpf"
        android:imeActionLabel="@string/str_next"
        android:imeOptions="actionUnspecified"
        android:inputType="textEmailAddress"
        android:maxLines="1"
        android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:id="@+id/et_cpf"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/cliente_cpf"
        android:imeActionId="@+id/cli_cpf"
        android:imeActionLabel="@string/str_next"
        android:imeOptions="actionUnspecified"
        android:inputType="number"
        android:maxLines="1"
        android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:id="@+id/et_endereco"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/cliente_endereco"
        android:imeActionId="@+id/cli_address"
        android:imeActionLabel="@string/str_next"
        android:imeOptions="actionUnspecified"
        android:inputType="textPostalAddress"
        android:maxLines="1"
        android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:id="@+id/et_bairro"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/cliente_bairro"
        android:imeActionId="@+id/cli_district"
        android:imeActionLabel="@string/str_next"
        android:imeOptions="actionUnspecified"
        android:inputType="text"
        android:maxLines="1"
        android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>

<Spinner
    android:id="@+id/sp_estados"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="16dp"/>

<Spinner
    android:id="@+id/sp_cidade"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="16dp"
    android:prompt="@string/cliente_cidade"/>

This ClienteEditActivity holds two fragments with different forms so I listen for a action menu click at the fragment, when menu is clicked I use this to call may validation:

if (!isValidEmail(etEmail)) {
     cancel = true;
     focusView = etEmail;
}
//after other validations
if (cancel){
   focusView.reqeustFocus();
} else {
   //save datas
}

The isValidEmail method is like this:

protected boolean isValidEmail(EditText editText) {

  validate = new Validate(editText);

  validate.addValidador(new ValidadorVazio(getContext()));
  validate.addValidador(new ValidadorEmail(getContext()));

  return validate.isValid();
}

My Validateclass looks like this:

public class Validate{
   private EditText etFonte;

   public Validate(EditText etFonte){
      this.etFonte = etFonte;
   }

   public void addValidador(AbstractValidador validador){
      lalidadores.add(validador);
   }

   public boolean isValid(){
      for (AbstractValidador validator : lValidadores) {
         try {
            if (!validator.isValid(etFonte.getText().toString())) {
               if(errorNotification != null) {
                  errorNotification.onInvalid(this);
               } else {
                  setSourceViewError(validator.getMessage(), validator.getErrorDrawable());
               }
               return false;
            } else {
               if(errorNotification != null) errorNotification.onValid(this);
            }
         } catch (ValidadorException e) {
            e.printStackTrace();
            if(errorNotification != null) {
               errorNotification.onInvalid(this);
            } else {
               setSourceViewError(e.getMessage(),validator.getErrorDrawable());
            }
            return false;
         }
      }
      etFonte.setError(null);
      return true;
   }

   private void setSourceViewError(String errorMessage, Drawable errorDrawable) {
      if(errorDrawable != null) {
         etFonte.setError(errorMessage, errorDrawable);
      } else {
        etFonte.setError(errorMessage);
      }
   }
}
Geshner Inagaki
  • 87
  • 2
  • 12
  • not sure but you can refer this thread http://stackoverflow.com/questions/10553920/small-edittext-have-a-seterror-with-a-lot-of-lines – Nik Jan 20 '16 at 18:37
  • Is this the behaviour in all the devices ? Seems really suspect. Why is it pointing to the editText at the top ? – Anudeep Bulla Jan 20 '16 at 18:44
  • Can you try on some emulators and other devices ? – Anudeep Bulla Jan 20 '16 at 18:44
  • @AnudeepBulla I tried with my phone (screen shot attached), and two more emulators (800 x 1280:xhdpi , API:19 and 480 x 800: hdpi, API:22) and got the same behaviour – Geshner Inagaki Jan 20 '16 at 19:00

4 Answers4

4

In your layout's root element, find the following line and remove it.

app:layout_behavior="@string/appbar_scrolling_view_behavior"

Everything will be fine!

Sreejin
  • 151
  • 7
4

Set error on TextInputLayout instead of EditText, Here's your code...

<android.support.design.widget.TextInputLayout
  android:id="@+id/textInputLayout"
  android:layout_width="match_parent"
  android:layout_height="wrap_content">

  <EditText
    android:id="@+id/et_nome"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="@string/cliente_nome"
    android:imeActionId="@+id/cli_name"
    android:imeActionLabel="@string/str_next"
    android:imeOptions="actionUnspecified"
    android:inputType="textPersonName"
    android:maxLines="1"
    android:singleLine="true"/>

Get your TextInputLayout at runtime and apply following code...

TextInputLayout textInputLayout = (TextInputLayout) findVeiwById(R.id.textInputLayout);
textInputLayout.setErrorEnabled(true);
textInputLayout.setError("Please enter a valid license number");

It will produce output something like this... enter image description here

User
  • 4,023
  • 4
  • 37
  • 63
0

I assume that you have set an error on wrong reference of edit text. You have to set error on the same edit email edit text and also have to request focus on same edit text.

Here is the code snippet for activity:-

private EditText mEmailET;
@Override
protected void onCreate(Bundle savedInstanceState) {

mEamilET = (EditText)findViewById(R.id.et_email);
}

private void setSourceViewError(String errorMessage, Drawable errorDrawable) {
  if(errorDrawable != null) {
     mEamilET.setError(errorMessage, errorDrawable);
     mEamilET.requestFocus();
} else {
    mEamilET.setError(errorMessage);
    mEamilET.requestFocus();
 }
}

If you still face the issue please send the activity code too for better understanding for us and appropriate answer.

0

Do not use "include" tag to show your layout. Just replace that tag with your layout and you good to go. And you would want to set marginTop="60dp" so the toolbar is accessible.