5
votes

I am using a view to enter user's four digit PIN. the UI consists of 4 edittext each having maxLength set to 1. On entering value to edit text1, focus is then shifted to the second edittext and so on. each Edittext input type is : numberPassword.

<EditText
            android:id="@+id/ed_1"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:gravity="center"
            android:inputType="numberPassword"
            android:maxLength="1" />

In java, to shift the focus, we have applied following text watcher to each of the edittext:

ed1.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (s.toString().length() == 1) {
                ed1.clearFocus();
                ed2.requestFocus();
                ed2.setCursorVisible(true);
            }
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

Problem is, value of edittext are not changing to *, it shows the real input number (not changing to password). Only 1st and last are changing to *, where as center two that means edittext 2 and edittext 3 are still have visible passwords.

Right now: We have 4 input Edittexts

desired output should be: | * | * | * | * |

When we fill the values, and switches the focus, by using java code specified, they get change to: (input value: 1234): | * | 2 | 3 | * |

If we focus back on either of the center edit texts, then value changes to password. Is it because of removing focus, and the transformation time required to change a field to password takes more time? Is there any method with which we can forcefully change the value to password.

5
Because you are not using this property for that two edit text. Set this property android:inputType="textPassword" and its done sirAndy Developer
I wish it would have been so easy. Every edittext is exact replicate of the one specified in the question. Each one has android:inputType="numberPassword"user3099103
Try putting the code in a Runnable, and post it, does it help?lionscribe
you can use Handler for delay so that it will change text. Check my answer belowArpit Prajapati
Have you find proper solution for this? I am also facing same issue.Nik

5 Answers

2
votes

Try running the following code for the previous text after the transitions

yourEditText.setTransformationMethod(new PasswordTransformationMethod());

it's a difficult method but

String e1,e2,e3,e4; 
@Override 
public void onTextChanged(CharSequence s, int start, int before, int count) { 
if (s.toString().length() == 1 && !ed1.getText().toString().equals("*")) { 
e1=ed1.getText(); 
ed1.setText("*"); 
ed2.requestFocus(); 
ed2.setCursorVisible(true); } }

you can use this method

1
votes

Because you set the maxLength to 1, so it will get single character only. Also you written code for clearFocus in the onTextChanged, so it will set focus to the next EditText. You have to change as like below in your xml.

<EditText
  android:id="@+id/ed_1"
  android:layout_width="20dp"
  android:layout_height="20dp"
  android:gravity="center"
  android:inputType="numberPassword"
  android:maxLength="4" />

Also remove the clearFocus in your onTextChanged().

1
votes

It seems like TextWatcher need some time to chenge it to password type, so i came up to this solution with using Handler and it works fine. Try below code

ed1.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (s.toString().length() == 1) {

            // use Handler for 1 second delay so that it will change text
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    ed2.requestFocus();
                }
            },1000);

        }
    }

    @Override
    public void afterTextChanged(Editable s) {

    }
});
0
votes

Just remove ed1.clearFocus(); from your code. Do not force the edittext to loose his focus, just tell the other edittext to regain the focus ed2.requestFocus(); . The previous edittext automatically remove its focus as soon as next edittext gain the focus. It will first transform the value then leave its focus.

0
votes

Just move your code from onTextChanged to afterTextChanged, and you don´t need clearFocus, just requestFocus.

This way you give time to obfuscate the number before change focus.