Страницы

Поиск по вопросам

пятница, 10 января 2020 г.

EditText: ввод цифр с преобразованием в формат “+7(XXX)XXX-XX-XX”

#android #android_edittext


Достал вот этот блок

edTelData.addTextChangedListener(new PhoneNumberFormattingTextWatcher() {
        //we need to know if the user is erasing or inputing some new character
        private boolean backspacingFlag = false;
        //we need to block the :afterTextChanges method to be called again after
we just replaced the EditText text
        private boolean editedFlag = false;
        //we need to mark the cursor position and restore it after the edition
        private int cursorComplement;

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            //we store the cursor local relative to the end of the string in the
EditText before the edition
            cursorComplement = s.length()-edTelData.getSelectionStart();
            //we check if the user ir inputing or erasing a character
            if (count > after) {
                backspacingFlag = true;
            } else {
                backspacingFlag = false;
            }
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // nothing to do here =D
        }

        @Override
        public void afterTextChanged(Editable s) {
            String string = s.toString();
            //what matters are the phone digits beneath the mask, so we always work
with a raw string with only digits
            String phone = string.replaceAll("[^\\d]", "");

            //if the text was just edited, :afterTextChanged is called another time...
so we need to verify the flag of edition
            //if the flag is false, this is a original user-typed entry. so we go
on and do some magic
            if (!editedFlag) {

                //we start verifying the worst case, many characters mask need to
be added
                //example: 999999999 <- 6+ digits already typed
                // masked: (999) 999-999
                if (phone.length() >= 7 && !backspacingFlag) {
                    //we will edit. next call on this textWatcher will be ignored
                    editedFlag = true;
                    //here is the core. we substring the raw digits and add the mask
as convenient
                    String ans = "+7(" + phone.substring(1, 4) + ") " + phone.substring(4,7)
+ "-" + phone.substring(7);
                    edTelData.setText(ans);
                    //we deliver the cursor to its original position relative to
the end of the string
                    edTelData.setSelection(edTelData.getText().length()-cursorComplement);

                    //we end at the most simple case, when just one character mask
is needed
                    //example: 99999 <- 3+ digits already typed
                    // masked: (999) 99
                } else if (phone.length() >= 4 && !backspacingFlag) {
                    editedFlag = true;
                    String ans = "+7(" +phone.substring(1, 4) + ") " + phone.substring(4);
                    edTelData.setText(ans);
                    edTelData.setSelection(edTelData.getText().length()-cursorComplement);
                }
                // We just edited the field, ignoring this cicle of the watcher and
getting ready for the next
            } else {
                editedFlag = false;
            }
        }
    });


сейчас, преобразует строку при вводе в формат 

+7(XXX)XXX-XXXX 
Пожалуйста, помогите переделать в +7(XXX)XXX-XX-XX (добавить второе "-")

ОБНОВЛЕНО

Спасибо за ответы, теперь снизу готовый исправленный код(можно копи-пастить)

edTelData.addTextChangedListener(new PhoneNumberFormattingTextWatcher() {
        //we need to know if the user is erasing or inputing some new character
        private boolean backspacingFlag = false;
        //we need to block the :afterTextChanges method to be called again after
we just replaced the EditText text
        private boolean editedFlag = false;
        //we need to mark the cursor position and restore it after the edition
        private int cursorComplement;

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            //we store the cursor local relative to the end of the string in the
EditText before the edition
            cursorComplement = s.length()-edTelData.getSelectionStart();
            //we check if the user ir inputing or erasing a character
            if (count > after) {
                backspacingFlag = true;
            } else {
                backspacingFlag = false;
            }
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // nothing to do here =D
        }

        @Override
        public void afterTextChanged(Editable s) {
            String string = s.toString();
            //what matters are the phone digits beneath the mask, so we always work
with a raw string with only digits
            String phone = string.replaceAll("[^\\d]", "");

            //if the text was just edited, :afterTextChanged is called another time...
so we need to verify the flag of edition
            //if the flag is false, this is a original user-typed entry. so we go
on and do some magic
            if (!editedFlag) {

                //we start verifying the worst case, many characters mask need to
be added
                //example: 999999999 <- 6+ digits already typed
                // masked: (999) 999-999
                if (phone.length() >= 9 && !backspacingFlag) {
                    //we will edit. next call on this textWatcher will be ignored
                    editedFlag = true;
                    //here is the core. we substring the raw digits and add the mask
as convenient
                    String ans = "+7(" + phone.substring(1, 4) + ") " + phone.substring(4,7)
+ "-" + phone.substring(7,9) + "-" + phone.substring(9);
                    edTelData.setText(ans);
                    //we deliver the cursor to its original position relative to
the end of the string
                    edTelData.setSelection(edTelData.getText().length()-cursorComplement);

                    //we end at the most simple case, when just one character mask
is needed
                    //example: 99999 <- 3+ digits already typed
                    // masked: (999) 99
                } else if (phone.length() >= 4 && !backspacingFlag) {
                    editedFlag = true;
                    String ans = "+7(" +phone.substring(1, 4) + ") " + phone.substring(4);
                    edTelData.setText(ans);
                    edTelData.setSelection(edTelData.getText().length()-cursorComplement);
                }
                // We just edited the field, ignoring this cicle of the watcher and
getting ready for the next
            } else {
                editedFlag = false;
            }
        }
    });


А это XML - код элемента:



    


Ответы

Ответ 1



Изменить условие if (phone.length() >= 7 && !backspacingFlag) на if (phone.length() >= 9 && !backspacingFlag) и String ans = "+7(" + phone.substring(1, 4) + ") " + phone.substring(4,7) + "-" + phone.substring(7); Изменить на: String ans = "+7(" + phone.substring(1, 4) + ") " + phone.substring(4,7) + "-" + phone.substring(7,9) + "-" + phone.substring(9);

Ответ 2



Есть небольшой косяк если стереть все и начать писать заново. Лечится проверкой на +7 if (phone.length() >= 4 && !backspacingFlag) { editedFlag = true; String beg=string.substring(0, 2); if ("+7".equals(beg)) { String ans = "+7(" + phone.substring(1, 4) + ") " + phone.substring(4); mEditTextPassword.setText(ans); mEditTextPassword.setSelection(mEditTextPassword.getText().length() - cursorComplement);} else { String ans = "+7(" + phone.substring(0, 3) + ") " + phone.substring(3); mEditTextPassword.setText(ans); mEditTextPassword.setSelection(mEditTextPassword.getText().length() - cursorComplement); } }

Комментариев нет:

Отправить комментарий