How to change the focus to next edit text in andro

2019-01-14 02:47发布

问题:

The User can enter only one digit in the edit text. if he enters the value in edtText1, I want the cursor automatically moves to edtText2 and so on. The user can able to edit the text which he/she has entered already. I tried the following way.

    edtPasscode1.setOnKeyListener(new OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            // TODO Auto-generated method stub
            if (edtPasscode1.getText().length() == 1)
                edtPasscode2.requestFocus();
            return false;
        }
    });

    edtPasscode2.setOnKeyListener(new OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            // TODO Auto-generated method stub
            if (edtPasscode2.getText().length() == 1)
                edtPasscode3.requestFocus();
            return false;
        }
    });

    edtPasscode3.setOnKeyListener(new OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            // TODO Auto-generated method stub
            if (edtPasscode3.getText().length() == 1)
                edtPasscode4.requestFocus();
            return false;
        }
    });

If the user edit the text, The cursor moves to some other editTexts and not working as desired. How can i achieve the above?

回答1:

Try TextWatcher instead of onKeyListener

B'coz if want to edit your password, in that case TextWatcher will give you more method to dealt with..

Edited:-

StringBuilder sb=new StringBuilder();

         edtPasscode1.addTextChangedListener(new TextWatcher() {
             public void onTextChanged(CharSequence s, int start, int before, int count) {
                 // TODO Auto-generated method stub
                 if(sb.length()==0&edtPasscode1.length()==1)
                 {
                     sb.append(s);
                     edtPasscode1.clearFocus();
                     edtPasscode2.requestFocus();
                     edtPasscode2.setCursorVisible(true);

                 }
             }

             public void beforeTextChanged(CharSequence s, int start, int count,
                     int after) {

                 if(sb.length()==1)
                 {

                     sb.deleteCharAt(0);

                 }

             }

             public void afterTextChanged(Editable s) {
                 if(sb.length()==0)
                 {

                     edtPasscode1.requestFocus();
                 }

             }
         });

Hope this work.



回答2:

set android:maxLength="1" to all your ExitText in xml

Try the following code

edtxt1 = (EditText) findViewById(R.id.edtxt_phonenumber_one);
        edtxt2 = (EditText) findViewById(R.id.edtxt_phonenumber_two);
        edtxt3 = (EditText) findViewById(R.id.edtxt_phonenumber_three);

        edtxt1.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable s) {

                if (s.length() ==1) {
                    edtxt2.requestFocus();
                }

            }

            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {
            }

            public void onTextChanged(CharSequence s, int start, int before,
                    int count) {
            }
        });

        edtxt2.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable s) {
                if (s.length() == 1) {
                    edtxt3.requestFocus();
                }

            }

            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {

            }

            public void onTextChanged(CharSequence s, int start, int before,
                    int count) {

            }
        });
        edtxt3.addTextChangedListener(new TextWatcher() {
            public void afterTextChanged(Editable s) {
                if (s.length() == 1) {
                    edtxt1.requestFocus();
                }

            }

            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {

            }

            public void onTextChanged(CharSequence s, int start, int before,
                    int count) {

            }
        });

This should work



回答3:

set the length to editetxt as android:maxLength="1" and follow the below code

((EditText) findViewById(R.id.edi1)).addTextChangedListener(new TextWatcher() {
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // TODO Auto-generated method stub
            if(((EditText) findViewById(R.id.edi1)).getText().toString().length()==1)
            {
                ((EditText) findViewById(R.id.edi1)).clearFocus();
                ((EditText) findViewById(R.id.edi2)).requestFocus();
                ((EditText) findViewById(R.id.edi2)).setCursorVisible(true);

            }
        }

        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {

            // TODO Auto-generated method stub

        }

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

        }


    });

    ((EditText) findViewById(R.id.edi2)).addTextChangedListener(new TextWatcher() {
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // TODO Auto-generated method stub
            if(((EditText) findViewById(R.id.edi2)).getText().toString().length()==1)
            {
                ((EditText) findViewById(R.id.edi2)).clearFocus();
                ((EditText) findViewById(R.id.edi3)).requestFocus();
                ((EditText) findViewById(R.id.edi3)).setCursorVisible(true);

            }
        }

        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {

            // TODO Auto-generated method stub

        }

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

        }


    });


    ((EditText) findViewById(R.id.edi3)).addTextChangedListener(new TextWatcher() {
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // TODO Auto-generated method stub
            if(((EditText) findViewById(R.id.edi3)).getText().toString().length()==1)
            {
                ((EditText) findViewById(R.id.edi3)).clearFocus();
                ((EditText) findViewById(R.id.edi4)).requestFocus();
                ((EditText) findViewById(R.id.edi4)).setCursorVisible(true);

            }
        }

        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {

            // TODO Auto-generated method stub

        }

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

        }


    });


回答4:

The solution coding is OK,

Below codes indicate that auto move to next Edit Text and auto move to previous Edit Text.

It also OK if you are using Rxjava + Data Binding + RxBinding in below :

// Show button Active code when enough fields active code
    Observable<Boolean> mObsPhoneVerify1 = RxTextView.textChanges(db.etPhoneVerify1)
            .observeOn(AndroidSchedulers.mainThread())
            .map(charSequence -> {
                if (!charSequence.toString().equals("")) {
                    db.etPhoneVerify2.requestFocus();
                    return true;
                } else {
                    db.etPhoneVerify1.requestFocus();
                    return false;
                }
            });
    Observable<Boolean> mObsPhoneVerify2 = RxTextView.textChanges(db.etPhoneVerify2)
            .observeOn(AndroidSchedulers.mainThread())
            .map(charSequence -> {
                if (!charSequence.toString().equals("")) {
                    db.etPhoneVerify3.requestFocus();
                    return true;
                } else {
                    db.etPhoneVerify1.requestFocus();
                    return false;
                }
            });
    Observable<Boolean> mObsPhoneVerify3 = RxTextView.textChanges(db.etPhoneVerify3)
            .observeOn(AndroidSchedulers.mainThread())
            .map(charSequence -> {
                if (!charSequence.toString().equals("")) {
                    db.etPhoneVerify4.requestFocus();
                    return true;
                } else {
                    db.etPhoneVerify2.requestFocus();
                    return false;
                }
            });
    Observable<Boolean> mObsPhoneVerify4 = RxTextView.textChanges(db.etPhoneVerify4)
            .observeOn(AndroidSchedulers.mainThread())
            .map(charSequence -> {
                if (!charSequence.toString().equals("")) {
                    hideKeyboard();
                    return true;
                } else {
                    /*
                    If enough text for  all fields, no need cursor
                    Otherwise, focus previous edit text
                     */
                    if (Utils.isValidEditText(db.etPhoneVerify1) && Utils.isValidEditText(db.etPhoneVerify2) && Utils.isValidEditText(db.etPhoneVerify3)) {
                        db.etPhoneVerify3.requestFocus();
                    } else {
                        db.etPhoneVerify1.clearFocus();
                        db.etPhoneVerify2.clearFocus();
                        db.etPhoneVerify3.clearFocus();
                        db.etPhoneVerify4.clearFocus();
                    }
                    return false;
                }
            });

   disposable = Observable
            .combineLatest(mObsPhoneVerify1, mObsPhoneVerify2, mObsPhoneVerify3, mObsPhoneVerify4,
                    (PhoneVerify1, PhoneVerify2, PhoneVerify3, PhoneVerify4)
                            -> PhoneVerify1 && PhoneVerify2 && PhoneVerify3 && PhoneVerify4)
            .compose(regisObserver(false))
            .subscribe(aBoolean -> {
                db.btnActiveCode.setEnabled(aBoolean);
            });


回答5:

This worked for my case, also max_length of edit text should be 1.

otp_1.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                    //
                }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                //
                if(editable.length()>0){
                    otp_1.clearFocus();
                    otp_2.requestFocus();
                    otp_2.setCursorVisible(true);
                }
            }
        });

        otp_2.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                //
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                //
                if(editable.length() > 0) {
                    otp_2.clearFocus();
                    otp_3.requestFocus();
                    otp_3.setCursorVisible(true);
                }
            }
        });

        otp_3.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                //
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                if(editable.length() > 0) {
                    otp_3.clearFocus();
                    otp_4.requestFocus();
                    otp_4.setCursorVisible(true);
                }
            }
        });


回答6:

You can use use a hidden EditText receive input, four TextView to display the password.

example:

dialog_passworld.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="10dip"
    android:paddingLeft="20dip"
    android:paddingRight="20dip"
    android:paddingTop="10dip" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Please enter a password"
        android:textSize="16sp" />

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="40dip"
        android:layout_marginTop="15dip" >

        <EditText
            android:id="@+id/passcode"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <LinearLayout
            android:id="@+id/passcode_container"
            android:layout_width="match_parent"
            android:layout_height="40dip"
            android:background="@drawable/password_border" >

            <TextView
                android:layout_width="0dip"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="@android:color/transparent"
                android:gravity="center"
                android:textSize="18sp"
                android:textStyle="bold" />

            <View
                android:layout_width="1px"
                android:layout_height="match_parent"
                android:background="@android:color/darker_gray" />

            <TextView
                android:layout_width="0dip"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="@android:color/transparent"
                android:gravity="center"
                android:textSize="16sp"
                android:textStyle="bold" />

            <View
                android:layout_width="1px"
                android:layout_height="match_parent"
                android:background="@android:color/darker_gray" />

            <TextView
                android:layout_width="0dip"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="@android:color/transparent"
                android:gravity="center"
                android:textSize="16sp"
                android:textStyle="bold" />

            <View
                android:layout_width="1px"
                android:layout_height="match_parent"
                android:background="@android:color/darker_gray" />

            <TextView
                android:layout_width="0dip"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="@android:color/transparent"
                android:gravity="center"
                android:textSize="16sp"
                android:textStyle="bold" />
        </LinearLayout>
    </FrameLayout>

</LinearLayout>

PasswordDialogBuilder.java

public class PasswordDialogBuilder extends AlertDialog.Builder {

    public PasswordDialogBuilder(Context context) {
        super(context, displayMetrics, eventManager);

        View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_password, null);

        LinearLayout passcodeContainer = (LinearLayout) contentView.findViewById(R.id.passcode_container);

        final List<TextView> passwordViews = new ArrayList<TextView>();

        int childCount = passcodeContainer.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childView = passcodeContainer.getChildAt(i);
            if (childView instanceof TextView) {
                passwordViews.add((TextView) childView);
            }
        }

        final int passwordCount = passwordViews.size();

        EditText passwordView = (EditText) contentView.findViewById(R.id.passcode);
        passwordView.setFilters(new InputFilter[] {new InputFilter.LengthFilter(passwordCount)});
        passwordView.setInputType(EditorInfo.TYPE_CLASS_NUMBER);
        passwordView.setCursorVisible(false);
        passwordView.setTextColor(Color.TRANSPARENT);
        passwordView.setBackgroundColor(Color.TRANSPARENT);
        passwordView.setSingleLine();

        passwordView.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {}

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void afterTextChanged(Editable s) {
                int passwordLength = s.length();

                for (int i = 0; i < passwordCount; i++) {
                    TextView passcodeView = passwordViews.get(i);
                    if (i < passwordLength) {
                        passcodeView.setText(String.valueOf(s.charAt(i)));
                    } else {
                        passcodeView.setText(StringUtils.EMPTY);
                    }
                }

                if (positiveButton != null) {
                    positiveButton.setEnabled(passwordLength == passwordCount);
                }
            }
        });

        setView(contentView);
    }
}