Search code examples
androidvalidationmvpbutterknifesaripaar

Saripaar Validation library throws No rules found error


I'm trying to use Saripaar Validation on my project, but it's throwing the following error:

java.lang.IllegalStateException: No rules found. You must have at least one rule to validate. If you are using custom annotations, make sure that you have registered them using the 'Validator.register()' method.

My architecture separates the responsibility for handling the view into a class, for example for LoginActivity I have LoginView, which is where I handle my view logic like ButterKnife injection, event listening, etc. In this class I have my annotated fields.My LoginView looks like this:

import android.content.res.ColorStateList;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.ImageViewCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatEditText;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;

import com.mobsandgeeks.saripaar.ValidationError;
import com.mobsandgeeks.saripaar.Validator;
import com.mobsandgeeks.saripaar.annotation.Email;
import com.mobsandgeeks.saripaar.annotation.NotEmpty;
import com.mobsandgeeks.saripaar.annotation.Password;
import com.serti.android.feenicia.validatortest.R;
import com.serti.android.feenicia.validatortest.screen.login.LoginActivity;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import rx.Observable;
import rx.subjects.PublishSubject;

public class LoginView implements Validator.ValidationListener {
    public static final String LOGIN_ACTION = "LOGIN";
    @BindView(R.id.login_button)
    Button loginButton;
    @BindView(R.id.username_edittext)
    @NotEmpty
    @Email
    AppCompatEditText usernameEditText;
    @BindView(R.id.password_edittext)
    @Password(min = 8, scheme = Password.Scheme.ALPHA_NUMERIC_MIXED_CASE_SYMBOLS)
    AppCompatEditText passwordEditText;
    @BindView(R.id.eye_imageview)
    ImageView eyeImageView;
    @BindView(R.id.loading_progressbar)
    ProgressBar loadingProgressBar;

    private boolean passwordIsVisible;

    private AlertDialog confirmPaymentDialog;
    private LoginActivity context;
    private View rootView;

    private PublishSubject<String> clickSubject = PublishSubject.create();

    Validator validator;

    public LoginView(LoginActivity context){
        this.context = context;
        FrameLayout parent = new FrameLayout(context);
        parent.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        rootView = LayoutInflater.from(context).inflate(R.layout.activity_login, parent, true);
        ButterKnife.bind(this, rootView);

        validator = new Validator(context);
        validator.setValidationListener(this);

        eyeImageView.setOnClickListener(v -> handleClick(v.getId()));
        loginButton.setOnClickListener(v -> handleClick(v.getId()));
        passwordIsVisible = false;
    }

    @Override
    public void onValidationSucceeded() {
        String action = null;
        Snackbar.make(rootView, "Validated", Snackbar.LENGTH_LONG).show();
        loginButton.setVisibility(View.GONE);
        loadingProgressBar.setVisibility(View.VISIBLE);
        action = LOGIN_ACTION;

        if(action != null){
            clickSubject.onNext(action);
        }
    }

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

    public String getUserName(){
        return usernameEditText.getText().toString();
    }
    public String getPassword(){
        return passwordEditText.getText().toString();
    }

    private void handleClick(int id){
        String action = null;
        switch (id){
            case R.id.login_button:
                validator.validate();
                break;
            case R.id.eye_imageview:
                togglePasswordVisibility();
        }
    }

    private void togglePasswordVisibility(){
        int color = 0;
        if(passwordIsVisible){
            passwordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance());
//            eyeImageView.setImageDrawable(context.getResources().getDrawable(R.drawable.eye_white));
            color = ContextCompat.getColor(context, R.color.dark_blue_button);
            ImageViewCompat.setImageTintList(eyeImageView, ColorStateList.valueOf(color));
        }else{
            passwordEditText.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
//            eyeImageView.setImageDrawable(context.getResources().getDrawable(R.drawable.eye_white));
            color = ContextCompat.getColor(context, R.color.dark_gray);
        }
        ImageViewCompat.setImageTintList(eyeImageView, ColorStateList.valueOf(color));
        passwordIsVisible = !passwordIsVisible;
        passwordEditText.setSelection(passwordEditText.getText().length());
    }

    private void showIncompleteCredentialsMessage() {
        Snackbar.make(loginButton, context.getText(R.string.incomplete_credentials_title), Snackbar.LENGTH_LONG).show();
    }

    public View getView(){
        return rootView;
    }
    public Observable<String> observeClicks(){
        return clickSubject;
    }
    public void openMainScreen(){
        context.startMainActivity();
    }

    public void openSearchTicketsScreen() {
        context.startSearchTicketsActivity();
    }

    public void showWrongCredentialsMessage() {
        loginButton.setVisibility(View.VISIBLE);
        loadingProgressBar.setVisibility(View.GONE);
        Snackbar.make(loginButton, context.getText(R.string.wrong_credentials_title), Snackbar.LENGTH_LONG).show();
    }

    public void setContext(LoginActivity context) {
        this.context = context;
    }
}

From what I'm guessing, the library is trying to find these fields on my Activity, and since they're not there, then it's throwing this error.

Is there a way use this library accordingly to the architecture I'm handling?


Solution

  • use validator = new Validator(this) in place of validator = new Validator(context);