为啥 EditText 验证时会出现两个错误标志?

Posted

技术标签:

【中文标题】为啥 EditText 验证时会出现两个错误标志?【英文标题】:Why two error signs is visible when EditText validate?为什么 EditText 验证时会出现两个错误标志? 【发布时间】:2017-04-19 20:12:06 【问题描述】:

对于验证,我使用了 saripaar 验证库。当表单无效时,它会给出一个带有消息的红色错误标志,但是当我点击错误字段时,另一个红色错误标志也出现了,这个额外的红色标志是意外的。如何删除这个额外的错误标志?

截图:

源代码:

package com.brainstation.ib.abbl.ui.activities;

import android.app.Dialog;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TextInputEditText;
import android.support.design.widget.TextInputLayout;
import android.support.v7.widget.AppCompatEditText;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.SpannableString;
import android.text.style.StyleSpan;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.basgeekball.awesomevalidation.AwesomeValidation;
import com.basgeekball.awesomevalidation.ValidationStyle;
import com.brainstation.ib.abbl.R;
import com.brainstation.ib.abbl.common.activities.TopMenuActivity;
import com.brainstation.ib.abbl.common.constant.MessageText;
import com.brainstation.ib.abbl.common.constant.PreferencesKey;
import com.brainstation.ib.abbl.common.enums.ResponseCode;
import com.brainstation.ib.abbl.common.model.BaseResponse;
import com.brainstation.ib.abbl.common.util.CustomLoadingDialog;
import com.brainstation.ib.abbl.model.activitylog.loglist.ActivityLogModel;
import com.brainstation.ib.abbl.model.authentication.ChangeLogInMessageModel;
import com.brainstation.ib.abbl.model.authentication.LoginPasswordChangeRequest;
import com.brainstation.ib.abbl.network.provider.ApiProvider;
import com.brainstation.ib.abbl.ui.adapter.NotificationListAdapter;
import com.mobsandgeeks.saripaar.ValidationError;
import com.mobsandgeeks.saripaar.Validator;
import com.mobsandgeeks.saripaar.annotation.ConfirmPassword;
import com.mobsandgeeks.saripaar.annotation.NotEmpty;
import com.mobsandgeeks.saripaar.annotation.Password;
import com.pixplicity.easyprefs.library.Prefs;
import com.weiwangcn.betterspinner.library.BetterSpinner;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class ChangeLoginPasswordActivity extends TopMenuActivity 

//AwesomeValidation awesomeValidation = new AwesomeValidation(ValidationStyle.BASIC);

@BindView(R.id.etCurrentPassword)
@NotEmpty
TextInputEditText etCurrentPassword;

@BindView(R.id.txtChangeLogInMessage)
TextView txtChangeLogInMessage;

@BindView(R.id.txtChangePassTitle)
TextView txtChangePassTitle;

@BindView(R.id.rootLinearLayout)
LinearLayout rootLinearLayout;

@BindView(R.id.textInputLayout1)
TextInputLayout textInputLayout1;

@BindView(R.id.textInputLayout2)
TextInputLayout textInputLayout2;

@BindView(R.id.textInputLayout3)
TextInputLayout textInputLayout3;

@BindView(R.id.etNewPassword)
@Password
TextInputEditText etNewPassword;

@BindView(R.id.etConfirmPassword)
@ConfirmPassword
TextInputEditText etConfirmPassword;

@BindView(R.id.top_menu)
LinearLayout topMenu;

private CustomLoadingDialog dialog;

private Validator validator;
private String authToken;
String message;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_change_login_password);

    //awesomeValidation.addValidation(ChangeLoginPasswordActivity.this, R.id.etCurrentPassword, "[a-zA-Z0-9_-]+", R.string.emptyError);
    ButterKnife.bind(this);
    setTopMenu();

    if (getIntent().getStringExtra("force") != null)
        topMenu.setVisibility(View.GONE);
    else 
        topMenu.setVisibility(View.VISIBLE);

    

    dialog = new CustomLoadingDialog(this);
    authToken = Prefs.getString(PreferencesKey.AUTH_TOKEN, null);
    callMessageApi();

    validator = new Validator(this);
    validator.setValidationListener(new Validator.ValidationListener() 
        @Override
        public void onValidationSucceeded() 
            callApi();
        

        @Override
        public void onValidationFailed(List<ValidationError> errors) 
            for (ValidationError error : errors) 
                View view = error.getView();
                String message = error.getCollatedErrorMessage(ChangeLoginPasswordActivity.this);
                if (view instanceof AppCompatEditText) 
                    ((AppCompatEditText) view).setError(message);
                
                if (view instanceof TextInputEditText) 
                    ((TextInputEditText) view).setError(message);
                 else if (view instanceof BetterSpinner) 
                    ((BetterSpinner) view).setError(message);
                 else 
                    Snackbar.make(rootLinearLayout, message, Snackbar.LENGTH_LONG).show();
                
            
        
    );

private void callApi() 
    dialog.show();
    LoginPasswordChangeRequest request = new LoginPasswordChangeRequest();
    request.setOldPassword(etCurrentPassword.getText().toString());
    request.setNewPassword(etNewPassword.getText().toString());
    request.setUserName(Prefs.getString(PreferencesKey.USER_ID, ""));
    request.setIpAddress("");
    Call<BaseResponse> call = ApiProvider.getApiClient().changeLoginPassword(authToken, request);
    call.enqueue(new Callback<BaseResponse>() 
        @Override
        public void onResponse(Call<BaseResponse> call, Response<BaseResponse> response) 
            if (response.isSuccessful()) 
                if (response.body().getResponseCode() == ResponseCode.OPERATION_SUCCESSFUL.getCode()) 
                    Snackbar.make(rootLinearLayout, "Password changed successfully", Snackbar.LENGTH_INDEFINITE)
                            .setAction("Done", new View.OnClickListener() 
                                @Override
                                public void onClick(View view) 
                                    Prefs.clear();
                                    Intent intent = new Intent(getApplicationContext(), LogInActivity.class);
                                    startActivity(intent);
                                
                            ).show();
                 else if (response.body().getResponseCode() == ResponseCode.AUTHENTICATION_FAILED.getCode()) 
                    if (getIntent().getStringExtra("force") != null) 
                        Toast.makeText(getApplicationContext(), "Mismatch Information.", Toast.LENGTH_LONG).show();
                     else 
                        Toast.makeText(getApplicationContext(), MessageText.TOKEN_EXPIRED_MSG, Toast.LENGTH_LONG).show();
                        gotoLogin();
                        finish();
                    

                 else if (response.body().getResponseCode() == ResponseCode.INVALID_ARGUMENT.getCode()) 
                    Snackbar.make(rootLinearLayout, response.body().getErrors().get(0), Snackbar.LENGTH_LONG).show();
                 else 
                    Snackbar.make(rootLinearLayout, MessageText.ERROR_MSG, Snackbar.LENGTH_LONG).show();
                
             else 
                Snackbar.make(rootLinearLayout, MessageText.ERROR_MSG, Snackbar.LENGTH_LONG).show();
            
            dialog.cancel();
        

        @Override
        public void onFailure(Call<BaseResponse> call, Throwable t) 
            dialog.cancel();
            Snackbar.make(rootLinearLayout, MessageText.ERROR_MSG, Snackbar.LENGTH_LONG).show();
        
    );


@OnClick(R.id.backBtn)
public void back(View view) 
    checkAuthAndGotoActivity(ChangeLoginPasswordActivity.this, ServicesActivity.class);


@OnClick(R.id.submitButton)
public void submit(View view) 
    validator.validate();


public void callMessageApi() 
    dialog.show();
    ApiProvider.getApiClient().getMessageChangeLogin(authToken).enqueue(new Callback<ChangeLogInMessageModel>() 
        @Override
        public void onResponse(Call<ChangeLogInMessageModel> call, Response<ChangeLogInMessageModel> response) 
            if (response.isSuccessful()) 
                message = response.body().getItems();
                showMessage();
                dialog.cancel();
             else 
                dialog.cancel();
                Snackbar.make(rootLinearLayout, response.body().getErrors().get(0).toString(), Snackbar.LENGTH_LONG).show();
            
        

        @Override
        public void onFailure(Call<ChangeLogInMessageModel> call, Throwable t) 
            Snackbar.make(rootLinearLayout, MessageText.ERROR_MSG, Snackbar.LENGTH_LONG).show();
        
    );


public void showMessage() 

    if (message == null) 

     else 
        String steps = "Note: " + message;
        String title = "Change Password";

        SpannableString ss1 = new SpannableString(title);
        ss1.setSpan(new StyleSpan(Typeface.BOLD), 0, ss1.length(), 0);
        txtChangePassTitle.append(ss1);
        txtChangePassTitle.append("\n");
        txtChangePassTitle.append(steps);
    


@Override
public void onBackPressed() 
    checkAuthAndGotoActivity(ChangeLoginPasswordActivity.this, ServicesActivity.class);
    overridePendingTransition(R.anim.left_to_right, R.anim.right_to_left);


【问题讨论】:

【参考方案1】:

view instanceof AppCompatEditTextview instanceof TextInputEditText 都返回 true。所以,它设置了两个错误图标。

您可以如下更改 onValidationFailed() 方法中的条件以避免这种情况。

if (view.getClass().getSimpleName().equalsIgnoreCase("AppCompatEditText")) 
            ((AppCompatEditText) view).setError(message);
 else if (view.getClass().getSimpleName().equalsIgnoreCase("TextInputEditText")) 
            TextInputLayout textInputLayout = (TextInputLayout) view.getParent().getParent();
            textInputLayout.setErrorEnabled(true);
            textInputLayout.setError(message);
 

【讨论】:

很好的解释......很久以前我提出了这个问题并解决了......谢谢:)【参考方案2】:

if(name.getText().toString().equalsIgnoreCase("")) name.setError("请输入 Adda 的名称"); enter code here

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于为啥 EditText 验证时会出现两个错误标志?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在安装SQL Sever Management Studio2012在功能选择时会出现此页验证有错误?

为啥这个程序在调用函数时会出现分段错误?

OCMock:为啥在尝试调用 UIWebView 模拟时会出现无法识别的选择器异常?

为啥在将 malloc() 的指针分配给 char* 时会出现段错误?

为啥在多个文件中使用结构时会出现“预期的结构文件 1::A 找到结构文件 2::A”错误?

为啥验证器方法返回true时会弹出一段时间的错误消息?