33

在此处输入图像描述

用户只能在编辑文本中输入一位数字。如果他在 edtText1 中输入值,我希望光标自动移动到 edtText2 等等。用户可以编辑他/她已经输入的文本。我尝试了以下方法。

    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;
        }
    });

如果用户编辑文本,光标将移动到其他一些编辑文本并且无法按预期工作。我怎样才能实现上述目标?

4

9 回答 9

44

尝试TextWatcher而不是onKeyListener

B'coz如果想编辑你的密码,在这种情况下TextWatcher会给你更多的方法来处理..

编辑:-

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();
                 }

             }
         });

希望这项工作。

于 2013-10-18T06:09:22.373 回答
11

设置android:maxLength="1"为你所有的ExitTextxml

试试下面的代码

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) {

            }
        });

这应该工作

于 2013-10-18T06:30:28.397 回答
4

将长度设置为 editetxtandroid:maxLength="1"并遵循以下代码

((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

        }


    });
于 2013-10-18T06:15:58.027 回答
4

首先在这里设置我在 xml 文件中EditText max length=1 取三个。EditText

<EditText
    android:id="@+id/edt1"
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:inputType="number"
    android:textAlignment="center"
    android:singleLine="true"
    android:maxLength="1"
    android:maxLines="1"
    android:imeOptions="actionNext"
    android:layout_margin="5dp"
    android:background="@drawable/edittext_shape_bg"/>


<EditText
    android:id="@+id/edt2"
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:inputType="number"
    android:textAlignment="center"
    android:singleLine="true"
    android:maxLength="1"
    android:imeOptions="actionNext"
    android:maxLines="1"
    android:layout_margin="5dp"
    android:background="@drawable/edittext_shape_bg"/>

<EditText
    android:id="@+id/edt3"
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:inputType="number"
    android:textAlignment="center"
    android:singleLine="true"
    android:maxLength="1"
    android:imeOptions="actionNext"
    android:maxLines="1"
    android:layout_margin="5dp"
    android:background="@drawable/edittext_shape_bg"/>

然后addTextChangeListener在每个EditText帮助您前进和后退的实施后。

这里我们StringBuilder用来获取最终字符串值。

edt1.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) {
          String edtChar=edt1.getText().toString();
          if(edtChar.length()==1)
          {
              currentCode.append(edtChar);

              edt2.requestFocus();
          }else if(edtChar.length()==0) {
            currentCode.deleteCharAt(0);
              edt1.requestFocus();
          }


      }
  });


    edt2.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) {
            String edtChar=edt2.getText().toString();
            if(edtChar.length()==1)
            {
                currentCode.append(edtChar);

                edt3.requestFocus();
            }else if(edtChar.length()==0) {
                currentCode.deleteCharAt(1);
                edt1.requestFocus();
            }


        }
    });
    edt3.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) {
            String edtChar=edt3.getText().toString();
            if(edtChar.length()==1)
            {
                currentCode.append(edtChar);

                edt4.requestFocus();
            }else if(edtChar.length()==0) {
                currentCode.deleteCharAt(2);
                edt2.requestFocus();
            }


        }
    });
于 2019-08-06T09:12:33.817 回答
1

这适用于我的情况,编辑文本的 max_length 也应该是 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);
                }
            }
        });
于 2017-06-23T20:26:46.397 回答
0

我也有同样的问题,我刚刚解决了,很简单。带有 .xml 文件。使用android:nextFocusDown="next_EditText_id"

前任:

<EditText
       android:id="@+id/edtUsername"
       android:nextFocusDown="@id/edtPassword"
       style="@style/EditText"
       />

<EditText
       android:id="@+id/edtPassword"
       style="@style/EditText.Password"
       />
于 2020-08-24T08:00:02.427 回答
0

我的 kotlin 解决方案

private fun addEditTextListener(editText: EditText?, nextEditText: EditText?) {
    editText?.setOnFocusChangeListener { view, focused ->
        if (focused) {
            editText.text = null
        }
    }
    editText?.addTextChangedListener {
        if (it.toString().isNotEmpty()) {
            if (nextEditText != null) {
                nextEditText.requestFocus()
            } else {
                viewModel.confirmCode(
                    binding?.digit1?.text?.toString(),
                    binding?.digit2?.text?.toString(),
                    binding?.digit3?.text?.toString(),
                    binding?.digit4?.text?.toString(),
                )
            }
        }

    }
}

并设置听众

 override fun setupViews() {
    addEditTextListener(binding?.digit1, binding?.digit2)
    addEditTextListener(binding?.digit2, binding?.digit3)
    addEditTextListener(binding?.digit3, binding?.digit4)
    addEditTextListener(binding?.digit4, null)
}
于 2020-11-02T09:28:16.473 回答
-1

解决方案编码OK,

下面的代码表示自动移动到下一个编辑文本并自动移动到上一个编辑文本。

如果您在下面使用Rxjava + Data Binding + RxBinding也可以:

// 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);
            });
于 2017-04-21T09:40:06.360 回答
-2

你可以使用一个隐藏的EditText接收输入,四个TextView来显示密码。

例子:

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>

PasswordDialogBu​​ilder.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);
    }
}
于 2014-09-03T08:42:01.253 回答