TextEdit验证叠加层显示密码图标

时间:2016-08-31 05:06:18

标签: android validation

我有一个密码TextEdit字段,我当前正在进行验证,它在TextEdit字段的末尾显示一个图标来切换实际文本。当有人输入错误的密码或密码不匹配时,会显示一个错误图标,表示输入的文本出错,此错误图标位于TextEdit字段的“show text”图标下方。如何从验证中移动错误图标,或如何移动“显示文本”图标?

app displaying both error icon and show text icon

RegisterActivity

public class RegisterActivity extends AppCompatActivity {
    private static final String TAG = "RegisterActivity";

    @InjectView(R.id.input_name) EditText _nameText;
    @InjectView(R.id.input_email) EditText _emailText;
    @InjectView(R.id.input_password) EditText _passwordText;
    @InjectView(R.id.input_confirmPassword) EditText _confirmPasswordText;
    @InjectView(R.id.btn_signup) Button _signupButton;
    @InjectView(R.id.link_login) TextView _loginLink;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        ButterKnife.inject(this);

        _signupButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                signup();
            }
        });

        _loginLink.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Finish the registration screen and return to the Login activity
                finish();
            }
        });
    }

    public void signup() {
        Log.d(TAG, "Begin Signup process...");

        if (!validate()) {
            onSignupFailed();
            return;
        }

        _signupButton.setEnabled(false);

        final ProgressDialog signupProgressDialog = new ProgressDialog(RegisterActivity.this,
                R.style.Theme_IAPTheme);
        signupProgressDialog.setIndeterminate(true);
        signupProgressDialog.setMessage("Creating Account...");
        signupProgressDialog.show();

        String name = _nameText.getText().toString();
        String email = _emailText.getText().toString();
        String password = _passwordText.getText().toString();
        String confirmPassword = _confirmPasswordText.getText().toString();

        // TODO: Implement your own signup logic here.

        Response.Listener<String> responseListener = new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    Log.i("tagconvertstr", "["+response+"]");
                    JSONObject jsonResponse = new JSONObject(response);
                    boolean success = jsonResponse.getBoolean("success");
                    if (success) {
                        onSignupSuccess();
                    } else {
                        onSignupFailed();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        };

        RegisterRequest registerRequest = new RegisterRequest(name, email, password, responseListener);
        RequestQueue queue = Volley.newRequestQueue(RegisterActivity.this);
        queue.add(registerRequest);

        /*new android.os.Handler().postDelayed(
                new Runnable() {
                    public void run() {

                        // On complete call either onSignupSuccess or onSignupFailed
                        // depending on success
                        onSignupSuccess();
                        // onSignupFailed();
                        progressDialog.dismiss();
                    }
                }, 3000);*/
    }

    public void onSignupSuccess() {
        Toast.makeText(getBaseContext(), "Signup Successful", Toast.LENGTH_LONG).show();
        _signupButton.setEnabled(true);
        setResult(RESULT_OK, null);
        finish();
    }

    public void onSignupFailed() {
        Toast.makeText(getBaseContext(), "Signup Failed", Toast.LENGTH_LONG).show();
        _signupButton.setEnabled(true);
    }

    public boolean validate() {
        boolean valid = true;
        boolean psisequal;

        String name = _nameText.getText().toString();
        String email = _emailText.getText().toString();
        String password = _passwordText.getText().toString();
        String confirmPassword = _confirmPasswordText.getText().toString();

        if (name.isEmpty() || name.length() < 3) {
            _nameText.setError("at least 3 characters");
            valid = false;
        } else {
            _nameText.setError(null);
        }

        if (email.isEmpty() || !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
            _emailText.setError("enter a valid email address");
            valid = false;
        } else {
            _emailText.setError(null);
        }

        if (password.isEmpty() || password.length() < 4 || password.length() > 10) {
            _passwordText.setError("between 4 and 10 alphanumeric characters");
            valid = false;
        }else {
            _passwordText.setError(null);
        }

        if (password.equals(confirmPassword)){
            _confirmPasswordText.setError(null);
            psisequal = true;
        }else {
            _confirmPasswordText.setError("passwords do not match");
            valid = false;
            psisequal = false;
        }

        return valid;
    }
}

activity_register

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fitsSystemWindows="true"
    android:background="@color/black">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="56dp"
        android:paddingLeft="24dp"
        android:paddingRight="24dp">

        <ImageView android:src="@drawable/logo"
            android:layout_width="wrap_content"
            android:layout_height="72dp"
            android:layout_marginBottom="24dp"
            android:layout_gravity="center_horizontal" />

        <!--  Name Label -->
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:textColor="#ffffff"
            android:textColorHint="#ffffff">
            <EditText android:id="@+id/input_name"
                android:theme="@style/MyEditTextTheme"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textCapWords"
                android:hint="Trainer Name (Gamer Tag)" />
        </android.support.design.widget.TextInputLayout>

        <!-- Email Label -->
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:textColor="#ffffff"
            android:textColorHint="#ffffff">
            <EditText android:id="@+id/input_email"
                android:theme="@style/MyEditTextTheme"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textEmailAddress"
                android:hint="E-Mail Address" />
        </android.support.design.widget.TextInputLayout>

        <!-- Password Label -->
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:textColor="#ffffff"
            android:textColorHint="#ffffff">
            <EditText android:id="@+id/input_password"
                android:theme="@style/MyEditTextTheme"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textPassword"
                android:hint="Password"/>
        </android.support.design.widget.TextInputLayout>

        <!-- Confirm Password Label -->
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:textColor="#ffffff"
            android:textColorHint="#ffffff">
            <EditText android:id="@+id/input_confirmPassword"
                android:theme="@style/MyEditTextTheme"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textPassword"
                android:hint="Confirm Password"/>
        </android.support.design.widget.TextInputLayout>

        <!-- Signup Button -->
        <android.support.v7.widget.AppCompatButton
            android:id="@+id/btn_signup"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:layout_marginBottom="24dp"
            android:padding="12dp"
            android:text="Create Account"/>

        <TextView android:id="@+id/link_login"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="24dp"
            android:text="Already a member? Login"
            android:textColor="#ffffff"
            android:gravity="center"
            android:textSize="16dip"/>

    </LinearLayout>
</ScrollView>

的字符串

<resources xmlns:android="http://schemas.android.com/tools">
    <string name="app_name">The World of Go</string>
    <string name="title_activity_maps">Map</string>
    <!--CODE FOR BUTTON OVERLAY-->
    <string name="Popular"></string>
    <string name="AZ"></string>
    <string name="Category"></string>
    <string name="NearBy"></string>
    <color name="bg_color">#ffffff</color>
    <color name="black">#222222</color>
    <color name="white">#ffffff</color>
    <style name="MyEditTextTheme">
        <item name="colorControlNormal">#ffffff</item>
        <item name="colorControlActivated">#ffffff</item>
        <item name="colorControlHighlight">#ffffff</item>
        <item name="colorAccent">@android:color/white</item>
        <item name="android:textColor">#ffffff</item>
        <item name="android:textColorHint">#ffffff</item> />
    </style>

    <string name="type_prompt">Choose a Type</string>
    <string-array name="type_arrays">
        <item>Pokestop</item>
        <item>Gym</item>
    </string-array>
</resources>

7 个答案:

答案 0 :(得分:2)

尝试使用这些方法来应用验证检查:

private TextInputLayout text_email,text_pass, text_confirm_pass;
private EditText email,pass,confirm_pass;

    text_pass = (TextInputLayout) findViewById(R.id.input_layout_password);
     email = (EditText) findViewById(R.id.email);

     private boolean validatePassword() {
            if (pass.getText().toString().trim().isEmpty()) {
                pass.setError(getString(R.string.err_msg_pass));
                requestFocus(text_pass);
                return false;
            }else if(pass.getText().toString().length()<8) {
                pass.setError(getString(R.string.err_msg_pass_length));
                requestFocus(text_pass);
                return false;
            }else {
                text_pass.setErrorEnabled(false);
            }
            return true;
        }

获得焦点:

 private void requestFocus(View view) {
        if (view.requestFocus()) {
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
    }

答案 1 :(得分:1)

这是我的解决方案

登录xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/grey"
    android:fillViewport="true">

    <LinearLayout
        android:id="@+id/login_form"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:padding="5dp"
            android:text="LOGIN"
            android:textSize="25sp" />

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp"
            android:textColor="#ffffff"
            android:textColorHint="#ffffff">

            <EditText
                android:id="@+id/etUserName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Trainer Name (Gamer Tag)"
                android:inputType="textCapWords"
                android:padding="10dp"
                android:singleLine="true"
                android:textAppearance="?android:attr/textAppearanceMedium" />
        </android.support.design.widget.TextInputLayout>

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp"
            android:textColor="#ffffff"
            android:textColorHint="#ffffff">

            <EditText
                android:id="@+id/etPassword"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:drawableRight="@drawable/ic_visibility_off_white_24dp"
                android:hint="Password"
                android:inputType="textPassword"
                android:padding="10dp"
                android:singleLine="true"
                android:textAppearance="?android:attr/textAppearanceMedium" />
        </android.support.design.widget.TextInputLayout>

        <Button
            android:id="@+id/btnSignIn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:text="Sign In"
            android:textColor="@android:color/white" />
    </LinearLayout>
</RelativeLayout>

登录课程

    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btnLogin;
    private EditText etUserName, etPassword;
    private String userName, password;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initValues();
    }

    private void initValues() {
        try {
            btnLogin = (Button) findViewById(R.id.btnSignIn);
            btnLogin.setOnClickListener(this);

            etUserName = (EditText) findViewById(R.id.etUserName);
            etPassword = (EditText) findViewById(R.id.etPassword);

            etPassword.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    final int DRAWABLE_RIGHT = 2;

                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
                        if (event.getRawX() >= (etPassword.getRight() - etPassword.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
                            if (etPassword.getInputType() == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
                                etPassword.setInputType(InputType.TYPE_CLASS_TEXT |
                                        InputType.TYPE_TEXT_VARIATION_PASSWORD);
                                etPassword.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_visibility_off_white_24dp, 0);
                                etPassword.setSelection(etPassword.getText().length());
                            } else {
                                etPassword.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
                                etPassword.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_visibility_white_24dp, 0);

                            }
                            return true;
                        }
                    }
                    return false;
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onClick(View v) {
        try {
            switch (v.getId()) {
                case R.id.btnSignIn:
                    validateCredentials();
                    onLogin();
                    break;
                default:
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void validateCredentials() {
        try {
            userName = etUserName.getText().toString();
            password = etPassword.getText().toString();
            if (TextUtils.isEmpty(userName) || TextUtils.isEmpty(password)) {
                etUserName.setError("enter a valid username");
                etPassword.setError("enter a correct password");
                return;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void onLogin() {
        //your login implementation
    }

}

<强>截图

enter image description here

enter image description here

enter image description here

答案 2 :(得分:0)

所以这就是我必须要解决的问题。我通过执行以下操作禁用了textEdit的标准文本视图:

app:passwordToggleEnabled="false"

这将禁用图标视图以切换密码可见性。然后我做的是添加一个imageView并添加我自己的眼睛图标到应用程序:

<ImageView
    android:id="@+id/imageView_registerPasswordVisibility"
    android:layout_width="24dp"
    android:layout_height="24dp"
    android:clickable="true"
    android:src="@drawable/eye"
    android:layout_row="4"
    android:layout_column="1"
    android:foregroundGravity="center_vertical"
    android:layout_gravity="center_vertical" />

我将布局转换为网格布局并将此图像视图放在下一列中以将其与textEdit的末尾对齐,这背后的原因是因为我们现在在textEdit之后显示图标而不是textEdit中的图标将出现错误验证图标的位置。这样做会解决冲突,我处理了imageView来做与passwordToggle相同的事情。所以这里是所有这些的完整代码,它还将显示如何在TextInputLayout上正确设置错误,如果这是您正在使用的。如果没有,那么就像通常那样设置错误(可以在标准的android文档中找到):

RegisterActivity.java

public class RegisterActivity extends AppCompatActivity {

    //Setup global variables for all of the user interface items.
    @InjectView(R.id.wrapper_registerPassword)
    TextInputLayout _registerPasswordWrapper; /*this is only needed for when you use TextInputLayout that gives us the ability to have animated hints by default. If you are ONLY using editText then you will not need the code for this wrapper.*/
    @InjectView(R.id.editText_registerPasswordInput)
    EditText _registerPasswordInput; /*This is to access text that was typed in the editText*/
    @InjectView(R.id.imageView_registerPasswordVisibility)
    ImageView _registerPasswordVisibility; /*This is used for our image that we will be adding listeners for to do speacial features when the image is pressed. */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        ButterKnife.inject(this);

        /*Set a listener for the password view image to display the text inside the password text
        field for when the image is pressed.*/
        _registerPasswordVisibility.setOnTouchListener(mPasswordVisibleTouchListener);
    }

    /*Listener for the toggle password icon.*/
    private View.OnTouchListener mPasswordVisibleTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            final boolean isOutsideView = event.getX() < 0 ||
                    event.getX() > v.getWidth() ||
                    event.getY() < 0 ||
                    event.getY() > v.getHeight();

            // change input type will reset cursor position, so we want to save it
            final int cursor = _registerPasswordInput.getSelectionStart();

            if (isOutsideView || MotionEvent.ACTION_UP == event.getAction())
            /*This will make the field display dots as a password text field should look like.*/
                _registerPasswordInput.setInputType( InputType.TYPE_CLASS_TEXT |
                        InputType.TYPE_TEXT_VARIATION_PASSWORD);
            else
            /*This will make the text in the password text field visibile while we are pressing down on our image.*/
                _registerPasswordInput.setInputType( InputType.TYPE_CLASS_TEXT |
                        InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);

            _registerPasswordInput.setSelection(cursor);
            return true;
        }
    };

    public boolean validate() {
        boolean valid = true;

        //Obtain user's entered in credentials to validate them.
        String password = _registerPasswordInput.getText().toString();

        //Password validation.
        if (password.isEmpty() || password.length() < 8 || password.length() > 30) {
            _registerPasswordWrapper.setError("Please provide a stronger password.\n" +
                    "•Password must be the following:\n" +
                    "•At least 8 characters");
            _registerPasswordWrapper.setErrorEnabled(true);
            valid = false;
        }else {
            _registerPasswordWrapper.setError(null);
        }

        return valid;
    }
}

activity_register.xml

    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:android.support.design="http://schemas.android.com/tools"
        android:fitsSystemWindows="true"
        android:background="@color/black">

        <!-- Start of Grid Layout -->
        <GridLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="56dp"
            android:paddingLeft="24dp"
            android:paddingRight="24dp"
            android:orientation="vertical">

            <!-- Password Text Field -->
            <android.support.design.widget.TextInputLayout
            android:id="@+id/wrapper_registerPassword"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:textColor="#ffffff"
            app:passwordToggleEnabled="false"
            android:textColorHint="#ffffff"
            android:layout_column="0"
            android:layout_row="4"
            android:layout_gravity="fill_horizontal">
            <android.support.design.widget.TextInputEditText
                android:id="@+id/editText_registerPasswordInput"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:maxLength="30"
                android:inputType="textPassword"
                android:hint="Password" />
        </android.support.design.widget.TextInputLayout>

        <!-- Password Toggle Icon for Password field -->
        <ImageView
            android:id="@+id/imageView_registerPasswordVisibility"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:clickable="true"
            android:src="@drawable/eye"
            android:layout_row="4"
            android:layout_column="1"
            android:foregroundGravity="center_vertical"
            android:layout_gravity="center_vertical" />

    </GridLayout>
</ScrollView>

我希望这可以帮助一些人,如果有人有任何问题,请让我知道并尽我所能帮助你!

答案 3 :(得分:0)

如果你只想显示一个图标,这可以解决问题。

更改PasswordVisibilityToggleTintMode属性。

您可以通过以下方式隐藏密码切换图标:

setPasswordVisibilityToggleTintMode(PorterDuff.Mode.CLEAR)

通过以下方式再次显示

setPasswordVisibilityToggleTintMode(PorterDuff.Mode.MULTIPLY)

答案 4 :(得分:0)

请为您XML中的TextInputLayout使用app:endIconDrawable="@null"

答案 5 :(得分:0)

首先,您需要将编辑文本包装在 TextInputLayout 中。 然后,当您将文本错误设置为某些内容时,您应该将 errorIconDrawable 设置为 null,这样它就不会覆盖切换密码图标。

像这样:

if (hasError) {
    textInputLayout.error = "Error text"
    textInputLayout.errorIconDrawable = null
}

答案 6 :(得分:0)

使用起来更方便:

<块引用>

TextInputLayout.isEndIconVisible

您可以通过设置 true 或 false 来显示或隐藏眼睛图标。

例如,当出现错误时,请执行此操作以隐藏眼睛图标以便错误图标可见:

 passwordTextInputLayout.isEndIconVisible = false

然后当用户再次开始输入时显示如下:

passTextView.afterTextChanged {

            passwordTextInputLayout.isEndIconVisible = true

        }