简体   繁体   中英

Android - Formatting phone number in EditText

I need a little assistance making this to work, because server side API requires special format for phone number field. Maybe I could edit that field just before sending API request by replacing characters at specific positions, however that would still give the user freedom to insert wrong format for phone number. I need to make EditText assist him just right after he changed the text and direct him to right format.

For that I have used TextWatcher method afterTextChanged() and format which I need is next: (063)22-22-333

This is what I have tried:

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

I'm getting an error after writing 4 character. Error is showing at the beginning.

You are using the split() method which needs as its 2nd parameter a regular expression and here is your problem: you need to escape "(" and ")" in regular expressions. So I made some changes:

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

Now you get no crash after the 3d char.
Every time you want to use split() instead of String.valueOf(brackets1) use brackets1 or sbrackets or sspace

You might have an easier time converting from a common format to the format that the server side is expecting. To get to a standard format, there are a couple of classes which already exist that might help you. Have you looked at PhoneNumberFormattingTextWatcher ?

If you absolutely need to use your own watcher, there are other utils that can help you:

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

After getting a predictable result, it should be trivial to convert to whatever your server needs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM