TheJadav

Custom PhoneTextWatcher in Android native for +1(xxx)-xxx-xxxx

Custom PhoneTextWatcher in Android native, Custom TextWatcher, TheJadav, +1(xxx)-xxx-xxxx

To implement custom PhoneTextWatcher in android native for +1(xxx)-xxx-xxxx format. We have PhoneNumberFormattingTextWatcher default available in Telephony class. But it is not enough for me. I want set format like below :    

So here is new TextWatcher class which can convert your input into above format:

import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;

public class PhoneNumberTextWatcher implements TextWatcher {

    //This TextWatcher sub-class formats entered numbers as 1 (123) 456-7890
    private boolean mFormatting; // this is a flag which prevents the
    // stack(onTextChanged)
    private boolean clearFlag;
    private int mLastStartLocation;
    private String mLastBeforeText;
    private EditText mWeakEditText;
    private int maxLength = 0;

    public PhoneNumberTextWatcher(EditText weakEditText, int length) {
        this.mWeakEditText = weakEditText;
        this.maxLength = length;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
                                  int after) {
        clearFlag = after == 0 && s.toString().equals(Watchers.PHONE_COUNTRY_CODE + " ");
        mLastStartLocation = start;
        mLastBeforeText = s.toString();
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before,
                              int count) {
        // TODO: Do nothing
    }

    @Override
    public void afterTextChanged(Editable s) {
        // Make sure to ignore calls to afterTextChanged caused by the work
        // done below
        if(!s.toString().isEmpty() && Character.isAlphabetic(s.charAt(0))){
//            mWeakEditText.removeTextChangedListener(this);
            return;
        }
        if (!mFormatting) {
            mFormatting = true;
            String formattedValue = formatNumber(s.toString(), clearFlag);
            mWeakEditText.removeTextChangedListener(this);
            int lengthBeforeUpdate = mWeakEditText.getText().length();
            int lengthAfterUpdate = formattedValue.length();
            int lastCursorPosition = mWeakEditText.getSelectionStart();
            mWeakEditText.setText(formattedValue);
            int newPosition = 0;
            if(lengthAfterUpdate < lengthBeforeUpdate){
                //It is deletion of character
                newPosition = lastCursorPosition - (lengthBeforeUpdate - lengthAfterUpdate);
            } else {
                newPosition = lastCursorPosition + (lengthAfterUpdate - lengthBeforeUpdate);
            }
            mWeakEditText.setSelection(Math.min(maxLength,Math.max(newPosition, 0)));
            mWeakEditText.addTextChangedListener(this);
            mFormatting = false;
        }
    }

    private String formatNumber(String currentInput, boolean clearFlag) {
        String clearedString = removeUnwantedCharacter(currentInput);
        StringBuilder outputString = new StringBuilder();
        clearedString = addPlusSignIfNotExist(clearedString);
        int totalDigitCount = clearedString.length();

        //if already entered 10 characters without country code then add country code
        if (totalDigitCount == 10 && !clearedString.startsWith(Watchers.PHONE_COUNTRY_CODE)) {
            outputString.append(Watchers.PHONE_COUNTRY_CODE + " ");
        }

        //Only country code then remove it
        if (clearedString.equals(Watchers.PHONE_COUNTRY_CODE) && clearFlag) {
            return "";
        }
        int alreadyPlacedDigitCount = 0;

        if (clearedString.startsWith(Watchers.PHONE_COUNTRY_CODE)) {
            outputString.append(Watchers.PHONE_COUNTRY_CODE + " ");
            alreadyPlacedDigitCount = Watchers.PHONE_COUNTRY_CODE.length();
        }

        if (totalDigitCount - alreadyPlacedDigitCount > 3) {
            outputString.append("(").append(clearedString.substring(alreadyPlacedDigitCount,
                    alreadyPlacedDigitCount + 3)).append(") ");

            alreadyPlacedDigitCount += 3;
        }

        if (totalDigitCount - alreadyPlacedDigitCount > 3) {
            outputString.append(clearedString.substring(
                    alreadyPlacedDigitCount, alreadyPlacedDigitCount + 3)).append("-");
            alreadyPlacedDigitCount += 3;
        }

        // All the required formatting is done so we'll just copy the
        // remaining digits.
        if (totalDigitCount > alreadyPlacedDigitCount) {
            outputString.append(clearedString
                    .substring(alreadyPlacedDigitCount));
            if (outputString.length() > maxLength) {
                String fullLength = outputString.toString();
                outputString.delete(0, outputString.length());
                outputString.append(fullLength.substring(0, maxLength));
            }
        }
        return outputString.toString();
    }

    private String addPlusSignIfNotExist(String clearedString) {
        if (Watchers.PHONE_COUNTRY_CODE.contains("+") && !clearedString.contains("+") && clearedString.length() > 10) {
            clearedString = "+" + clearedString;
        }
        return clearedString;
    }

    private String removeUnwantedCharacter(String currentInput) {
        StringBuilder clearedString = new StringBuilder();
        int p = 0;
        while (p < currentInput.length()) {
            char ch = currentInput.charAt(p);
            if (Character.isDigit(ch) || (ch == '+' && p == 0)) {
                clearedString.append(ch);
            }
            p++;
        }
        return clearedString.toString();
    }
}

Here is only one parameter is not available in code that is length, let me define it here so you will only get 10 digit mobile number with country code in pretty format.

int formattingSupporterLength = 5; //chracters which will be used in formatting number (, ,), ,-,
int length = PHONE_COUNTRY_CODE.length() + 10 + formattingSupporterLength;

For country code I have used +1 you can also use any code here.

PHONE_COUNTRY_CODE = “+1”

Feel free to copy and paste code. Contribute your knowledge here so other can also copy and fasten their development.

I have added comment for each section, so you can better understand how code works and also modify according to your requirement. 

????????*Posted In India* ????????

⌨️ Happy Coding ⌨️

Share this content:

Share:

More Posts

How does data persistence work in Android?

Data persistence in Android is the ability to save data to the device so that it can be accessed later, even if the app is closed or the device is restarted. There are several ways to achieve data persistence in Android

Fragments and Activities: Two Pillars of Android Development

Fragments and Activities are both important components of Android development. Fragments are a good choice for creating reusable and dynamic UIs, while Activities are a good choice for managing the lifecycle of an app’s UI and implementing core features.

Table of Contents

Send Us A Message