FileDocCategorySizeDatePackage
PhoneNumberFormattingTextWatcher.javaAPI DocAndroid 5.1 API5966Thu Mar 12 22:22:42 GMT 2015android.telephony

PhoneNumberFormattingTextWatcher

public class PhoneNumberFormattingTextWatcher extends Object implements android.text.TextWatcher
Watches a {@link android.widget.TextView} and if a phone number is entered will format it.

Stop formatting when the user

  • Inputs non-dialable characters
  • Removes the separator in the middle of string.

The formatting will be restarted once the text is cleared.

Fields Summary
private boolean
mSelfChange
Indicates the change was caused by ourselves.
private boolean
mStopFormatting
Indicates the formatting has been stopped.
private com.android.i18n.phonenumbers.AsYouTypeFormatter
mFormatter
Constructors Summary
public PhoneNumberFormattingTextWatcher()
The formatting is based on the current system locale and future locale changes may not take effect on this instance.


                             
      
        this(Locale.getDefault().getCountry());
    
public PhoneNumberFormattingTextWatcher(String countryCode)
The formatting is based on the given countryCode.

param
countryCode the ISO 3166-1 two-letter country code that indicates the country/region where the phone number is being entered.

        if (countryCode == null) throw new IllegalArgumentException();
        mFormatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(countryCode);
    
Methods Summary
public synchronized voidafterTextChanged(android.text.Editable s)

        if (mStopFormatting) {
            // Restart the formatting when all texts were clear.
            mStopFormatting = !(s.length() == 0);
            return;
        }
        if (mSelfChange) {
            // Ignore the change caused by s.replace().
            return;
        }
        String formatted = reformat(s, Selection.getSelectionEnd(s));
        if (formatted != null) {
            int rememberedPos = mFormatter.getRememberedPosition();
            mSelfChange = true;
            s.replace(0, s.length(), formatted, 0, formatted.length());
            // The text could be changed by other TextWatcher after we changed it. If we found the
            // text is not the one we were expecting, just give up calling setSelection().
            if (formatted.equals(s.toString())) {
                Selection.setSelection(s, rememberedPos);
            }
            mSelfChange = false;
        }
        PhoneNumberUtils.ttsSpanAsPhoneNumber(s, 0, s.length());
    
public voidbeforeTextChanged(java.lang.CharSequence s, int start, int count, int after)

        if (mSelfChange || mStopFormatting) {
            return;
        }
        // If the user manually deleted any non-dialable characters, stop formatting
        if (count > 0 && hasSeparator(s, start, count)) {
            stopFormatting();
        }
    
private java.lang.StringgetFormattedNumber(char lastNonSeparator, boolean hasCursor)

        return hasCursor ? mFormatter.inputDigitAndRememberPosition(lastNonSeparator)
                : mFormatter.inputDigit(lastNonSeparator);
    
private booleanhasSeparator(java.lang.CharSequence s, int start, int count)

        for (int i = start; i < start + count; i++) {
            char c = s.charAt(i);
            if (!PhoneNumberUtils.isNonSeparator(c)) {
                return true;
            }
        }
        return false;
    
public voidonTextChanged(java.lang.CharSequence s, int start, int before, int count)

        if (mSelfChange || mStopFormatting) {
            return;
        }
        // If the user inserted any non-dialable characters, stop formatting
        if (count > 0 && hasSeparator(s, start, count)) {
            stopFormatting();
        }
    
private java.lang.Stringreformat(java.lang.CharSequence s, int cursor)
Generate the formatted number by ignoring all non-dialable chars and stick the cursor to the nearest dialable char to the left. For instance, if the number is (650) 123-45678 and '4' is removed then the cursor should be behind '3' instead of '-'.

        // The index of char to the leftward of the cursor.
        int curIndex = cursor - 1;
        String formatted = null;
        mFormatter.clear();
        char lastNonSeparator = 0;
        boolean hasCursor = false;
        int len = s.length();
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (PhoneNumberUtils.isNonSeparator(c)) {
                if (lastNonSeparator != 0) {
                    formatted = getFormattedNumber(lastNonSeparator, hasCursor);
                    hasCursor = false;
                }
                lastNonSeparator = c;
            }
            if (i == curIndex) {
                hasCursor = true;
            }
        }
        if (lastNonSeparator != 0) {
            formatted = getFormattedNumber(lastNonSeparator, hasCursor);
        }
        return formatted;
    
private voidstopFormatting()

        mStopFormatting = true;
        mFormatter.clear();