44

I have a couple of edit text boxes on a single line. After the user types in a specific number of characters in the first I want to automatically move to the next edit text. How do I achieve this?

user1667307
  • 2,041
  • 6
  • 27
  • 32

4 Answers4

77

You can achieve this by using the Text Watcher class and then set the focus on the next EditText in the OnTextChanged() method of the TextWatcher.

In your case, since you have two Edit Texts, say et1 and et2. You can try out the following code:-

et1.addTextChangedListener(new TextWatcher() {

    public void onTextChanged(CharSequence s, int start,int before, int count) 
    {
        // TODO Auto-generated method stub
        if(et1.getText().toString().length()==size)     //size as per your requirement
        {
            et2.requestFocus();
        }
    }
    public void beforeTextChanged(CharSequence s, int start,
                    int count, int after) {
                // TODO Auto-generated method stub

    }

    public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub
    }

});

I have not checked out the code myself, but I hope this will help you solve your problem.

Shekhar Chikara
  • 3,786
  • 2
  • 29
  • 52
  • It helped, but I am facing a issue after the second edittext focus is not going to 3rd edittext. I have total 4 edittext. – Sidhartha May 12 '18 at 08:34
  • 2
    What if i have more than 6 edittexts and i want to apply the same code to every ediitext? I don't want to repeat my code for all 6 ediitexts! – Priyanka Alachiya Oct 30 '18 at 04:53
27

There is a simpler way to do this which doesn't involve knowledge of the ids of the EditText views. For use with android:maxLength="1".

// onTextChanged
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
    TextView text = (TextView)getCurrentFocus();

    if (text != null && text.length() > 0)
    {
        View next = text.focusSearch(View.FOCUS_RIGHT); // or FOCUS_FORWARD
        if (next != null)
            next.requestFocus();

        doSearch(); // Or whatever
    }
}

// afterTextChanged
@Override
public void afterTextChanged(Editable s) {}

// beforeTextChanged
@Override
public void beforeTextChanged(CharSequence s, int start,
                              int count, int after) {}
Bill Farmer
  • 271
  • 3
  • 5
4

The accepted answer is good.

I provide new way if you are using RxJava + RxBinding library.

The coding indicate 4 input Edit Text need verify (My case is Active code SMS via Phone - Phone Verify)

// Show button Active code when enough fields active code
    Observable<Boolean> mObsPhoneVerify1 = RxTextView.textChanges(db.etPhoneVerify1)
            .observeOn(AndroidSchedulers.mainThread())
            .map(charSequence -> {
                        db.etPhoneVerify2.requestFocus();
                        return charSequence != null && !charSequence.toString().equals("");
                    }
            );
    Observable<Boolean> mObsPhoneVerify2 = RxTextView.textChanges(db.etPhoneVerify2)
            .observeOn(AndroidSchedulers.mainThread())
            .map(charSequence -> {
                db.etPhoneVerify3.requestFocus();
                return charSequence != null && !charSequence.toString().equals("");
            });
    Observable<Boolean> mObsPhoneVerify3 = RxTextView.textChanges(db.etPhoneVerify3)
            .observeOn(AndroidSchedulers.mainThread())
            .map(charSequence -> {
                db.etPhoneVerify4.requestFocus();
                return charSequence != null && !charSequence.toString().equals("");
            });
    Observable<Boolean> mObsPhoneVerify4 = RxTextView.textChanges(db.etPhoneVerify4)
            .observeOn(AndroidSchedulers.mainThread())
            .map(charSequence -> {
                db.etPhoneVerify1.requestFocus();

                hideKeyboard();
                return charSequence != null && !charSequence.toString().equals("");
            });

    disposable = Observable
            .combineLatest(mObsPhoneVerify1, mObsPhoneVerify2, mObsPhoneVerify3, mObsPhoneVerify4,
                    (PhoneVerify1, PhoneVerify2, PhoneVerify3, PhoneVerify4)
                            -> PhoneVerify1 && PhoneVerify2 && PhoneVerify3 && PhoneVerify4)
            .compose(regisObserver(false))
            .subscribe(aBoolean -> {
                db.btnActiveCode.setEnabled(aBoolean);
            });
    busDisposables.add(disposable);
Huy Tower
  • 7,769
  • 16
  • 61
  • 86
  • Is there a combined solution with this to achieve in backward focusing as well? Like. If I clear EditText4 it then Edittext 3 should be focused. – Milind Mevada Nov 21 '18 at 10:43
3

If you have a list of TextViews for which you want to shift focus (like getting OTP input) then the following code will help achieve it in less number of lines

TextView otp1 = (TextView) root.findViewById(R.id.edit_verify_otp1);
TextView otp2 = (TextView) root.findViewById(R.id.edit_verify_otp2);
TextView otp3 = (TextView) root.findViewById(R.id.edit_verify_otp3);
TextView otp4 = (TextView) root.findViewById(R.id.edit_verify_otp4);

/* Assign the TextViews in the array in the order in which you want to shift focus */
TextView[] otpTextViews = {otp1, otp2, otp3, otp4}; 

    for (TextView currTextView : otpTextViews) {
        currTextView.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) {
                nextTextView().requestFocus();
            }

            @Override
            public void afterTextChanged(Editable s) {
            }

            public TextView nextTextView() {
                int i;
                for (i = 0; i < otpTextViews.length - 1; i++) {
                    if (otpTextViews[i] == currTextView)
                        return otpTextViews[i + 1];
                }
                return otpTextViews[i];
            }
        });
    }
Srini
  • 178
  • 1
  • 6