Replace the text in an EditText of maxLength 1 when new text is entered

时间:2018-10-02 09:09:46

标签: android android-edittext

I am creating a screen where the user can enter a 4 digit pin code, and to do this I am using several EditText widgets with a maxlength of 1. What I want to achieve is that when an EditText is already filled in with a digit, the user should be able to replace that digit with another by simply giving another input.

I am using a TextWatcher to perform actions when the text has been edited. One idea I had was to set the maxlength to 2 and clear the EditText in beforeTextChanged. However, this method results in the first input clearing the field, and then the user has to give an input again to fill the field.

    private final TextWatcher textWatcher = new TextWatcher() {
    boolean _ignore = false;

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

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

        _ignore = true;
        EditText current = (EditText) getActivity().getCurrentFocus();
        if (current != null && current.length() > 0) {
            current.setText("");
        }
        _ignore = false;
    }

    @Override
    public void afterTextChanged(Editable s) {
        if (_ignore) { return; }
    }
};

A similar question was asked here, but all the answers were either wrong or missing the point. This does not seem like such an obscure case to me, so it is weird that I have not been able to find anything online. Any input would be appreciated!

2 个答案:

答案 0 :(得分:1)

You were going well! Set maxLenght to 2, and on text changed, check the input size. If it is 2, clear the first digit. This way, you won't clear it the first time the user enters the digit.

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    if (s.length() >= 2) {
        editText.setText(s.toString().substring(s.length() - 1, s.length()));
    }
}

答案 1 :(得分:0)

接受的响应有问题,如果用户点击第一个字符后面的编辑文本怎么办?然后它将文本设置为那里的最后一个字符,也就是它已经存在的字符。您需要检查与编辑中的最后一个值的差异

 fun addWatcher(editText: EditText, editTextToFocus: EditText) {
        var beforeText: CharSequence = ""
        val textWatched = object : TextWatcher {
            override fun beforeTextChanged(
                s: CharSequence,
                start: Int,
                count: Int,
                after: Int
            ) {
            }

            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
                if (s.length >= 2) {
                    val beforeChars = beforeText.toList()
                    val newChar = s.toList().firstOrNull {
                        !beforeChars.contains(it)
                    } ?: s.toString().substring(s.length - 1, s.length)
                    editText.setText(newChar.toString())
                }
            }

            override fun afterTextChanged(s: Editable) {
                beforeText = s.toString()
                editTextToFocus.requestFocus()
            }

        }
        editText.addTextChangedListener(textWatched)
    }