Android - форматирование номера телефона в EditText - PullRequest
0 голосов
/ 26 августа 2018

Мне нужна небольшая помощь, чтобы это работало, потому что API на стороне сервера требует специального формата для поля номера телефона.Возможно, я мог бы отредактировать это поле непосредственно перед отправкой запроса API, заменив символы в определенных позициях, однако это все равно предоставило бы пользователю свободу вставлять неправильный формат для номера телефона.Мне нужно, чтобы EditText помог ему сразу после того, как он изменил текст и направил его в нужный формат.

Для этого я использовал метод TextWatcher afterTextChanged(), и мне нужен следующий формат: (063)22-22-333

Вот что я пробовал:

private static final char space = '-';
private static final char brackets = '(';
private static final char brackets1 = ')';

etPhone.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) {
            // (063)22-22-333

            // -> Error

            if (s.length() > 0 && !s.toString().startsWith("(")) {
                s.replace(0, s.length(), "(0");
            }

            if (s.length() > 0 && s.length() == 8) {
                final char c = s.charAt(s.length() - 1);
                if (space == c) {
                    s.delete(s.length() - 1, s.length());
                }
            } else if (s.length() > 0 && s.length() == 5) {
                final char c = s.charAt(s.length() - 1);
                if (brackets1 == c) {
                    s.delete(s.length() - 1, s.length());
                }
            }

            // Insert char where needed.
            if (s.length() > 0 && s.length() == 8) {
                char c = s.charAt(s.length() - 1);
                // Only if its a digit where there should be a space we insert a space
                if (Character.isDigit(c) && TextUtils.split(s.toString(), String.valueOf(space)).length <= 7) {
                    s.insert(s.length() - 1, String.valueOf(space));
                }
            } else if (s.length() > 0 && s.length() == 5) {
                char c = s.charAt(s.length() - 1);
                if (Character.isDigit(c) && TextUtils.split(s.toString(), String.valueOf(brackets1)).length <= 4) {
                    s.insert(s.length() - 1, String.valueOf(brackets1));
                }
            }
        }
    });

Я получаю сообщение об ошибке после написания 4 символов.Ошибка отображается в начале.

Ответы [ 2 ]

0 голосов
/ 26 августа 2018

Возможно, вам будет проще конвертировать из общего формата в формат, ожидаемый на стороне сервера. Чтобы перейти к стандартному формату, существует пара классов, которые уже могут вам помочь. Вы смотрели на PhoneNumberFormattingTextWatcher?

Если вам абсолютно необходимо использовать свой собственный наблюдатель, есть другие утилиты, которые могут вам помочь:

// this will result in the string "(212) 555-2232"
String number = PhoneNumberUtils.formatNumber("2125552232", "US")

Получив предсказуемый результат, легко перейти к тому, что нужно вашему серверу.

0 голосов
/ 26 августа 2018

Вы используете метод split (), которому в качестве второго параметра требуется регулярное выражение, и вот ваша проблема: вам нужно экранировать "(" и ")" в регулярных выражениях.Поэтому я внес некоторые изменения:

private static final char space = '-';
private static final char brackets = '(';
private static final char brackets1 = ')';
private static final String sspace = "\\x32";
private static final String sbrackets = "\\x28";
private static final String sbrackets1 = "\\x29";

    etPhone.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) {
            // (063)22-22-333

            // -> Error

            if (s.length() > 0 && !s.toString().startsWith("(")) {
                s.replace(0, s.length(), "(0");
            }

            if (s.length() > 0 && s.length() == 8) {
                final char c = s.charAt(s.length() - 1);
                if (space == c) {
                    s.delete(s.length() - 1, s.length());
                }
            } else if (s.length() > 0 && s.length() == 5) {
                final char c = s.charAt(s.length() - 1);
                if (brackets1 == c) {
                    s.delete(s.length() - 1, s.length());
                }
            }

            // Insert char where needed.
            if (s.length() > 0 && s.length() == 8) {
                char c = s.charAt(s.length() - 1);
                // Only if its a digit where there should be a space we insert a space
                if (Character.isDigit(c) && TextUtils.split(s.toString(), sspace).length <= 7) {
                    s.insert(s.length() - 1, String.valueOf(space));
                }
            } else if (s.length() > 0 && s.length() == 5) {
                char c = s.charAt(s.length() - 1);
                if (Character.isDigit(c) && TextUtils.split(s.toString(), sbrackets1).length <= 4) {
                    s.insert(s.length() - 1, String.valueOf(brackets1));
                }
            }
        }
    });

Теперь вы не получите сбоев после 3d персонажа.Каждый раз, когда вы хотите использовать split () вместо String.valueOf(brackets1), используйте brackets1 или sbrackets или sspace

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...