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

Introduction to Kotlin: A Versatile and Modern Programming Language

Kotlin, a versatile and modern programming language, offers developers a concise, safe, and interoperable coding experience. With features like null safety, extension functions, and coroutines, Kotlin enhances productivity and readability, making it an attractive choice for Android development and beyond. Whether you’re new to programming or an experienced developer, exploring Kotlin opens up a world of possibilities for building robust and expressive applications.

Mastering the Android Activity Lifecycle: A Comprehensive Guide

The Android Activity Lifecycle is a fundamental concept for Android developers. It defines how an Activity behaves during its lifecycle, from creation to destruction. Understanding the Activity Lifecycle is crucial for managing resources efficiently and delivering a smooth user experience. In this blog post, we’ll briefly introduce the different states an Activity can be in and the main callback methods associated with each state. Let’s dive in and explore this important aspect of Android app development!

Table of Contents

Send Us A Message