Кастомная форма для ввода пароля

Рейтинг: 2Ответов: 1Опубликовано: 02.04.2015

Здравствуйте!

Делаю кастомную форму для ввода кода. Вот как на картинке.

Идея у меня возникла сделать фон для EditText, на фоне разделители. Но ширина отступа между символами в EditText регулируется XML атрибутом letterSpacing, который поддерживается с 21 версии API, что не подходит.

Если самому добавлять пробелы после символов, то не понятно, сколько их нужно для маленького телефона или для большого.

Следующая идея это сделать 6 editTextов и обрабатывать события в них TextWatcherом afrerTextChanged, и удалять символы перехватывая KeyEvent.KEYCODE_DEL, вышел бардак.

Потому, что TextWatcher, как мне кажется не надежная штука. Остается только показывать свою клавиатуру, и обрабатывать нажатия на её клавиши. Подскажите как обычно вы выходите из подобной ситуации? Или как мне лучше поступить?

На всякий случай мой код...

p.s. задача поставлена чтобы сделать также как и на картинке. введите описание изображения здесь

Ответы

▲ 2Принят

Решил вопрос-таки.

public class MainActivity extends ActionBarActivity {

List<EditText> confirmationInput = new ArrayList<>(6);

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initInput();
    initInputParams();
    setSelected(0);
}

private void setSelected(int i) {
    confirmationInput.get(i).requestFocus();
    confirmationInput.get(i).setEnabled(true);

}

private void deselect(int i) {
    confirmationInput.get(i).setClickable(false);
    confirmationInput.get(i).setEnabled(false);
}

private void initInput() {
    confirmationInput.add((EditText) findViewById(R.id.input_1));
    confirmationInput.add((EditText) findViewById(R.id.input_2));
    confirmationInput.add((EditText) findViewById(R.id.input_3));
    confirmationInput.add((EditText) findViewById(R.id.input_4));
}

private void initInputParams() {
    for (EditText text : confirmationInput) {
        text.setSelected(false);
        text.setClickable(false);
        text.setEnabled(false);
        text.setCursorVisible(false);
        setTextWatcher(text);
    }
}

private void setTextWatcher(final EditText editText) {

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

        }

        @Override
        public void afterTextChanged(Editable s) {
            if (editText.getText().length() > 0) {
                goNext(editText);
            } else {
                goPrevious(editText);
            }
        }
    });

    editText.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_DEL) {
                if (isEmpty(editText)) {
                    goPrevious(editText);
                }
                return false;
            }
            return false;
        }
    });
}

private boolean isEmpty(EditText editText) {
    return editText.getText().toString().equals("");
}

private void goPrevious(EditText txt) {
    int idx = confirmationInput.indexOf(txt);
    if (idx == 0) return;
    setSelected(idx-1);
    deselect(idx);

}

private void goNext(EditText txt) {
    int idx = confirmationInput.indexOf(txt);
    if (idx == 3) return;
    setSelected(idx+1);
    deselect(idx);
}

xml. Ну тут разберётесь, ниже приведен типичный инпут

<EditText
            android:id="@+id/input_1"
            android:maxLength="1"
            android:windowSoftInputMode="stateVisible"
            android:clickable="false"
            android:inputType="numberPassword"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content" />