Home » Android » textwatcher – Automatically add dash in phone number in Android

textwatcher – Automatically add dash in phone number in Android

Posted by: admin May 14, 2020 Leave a comment

Questions:

Instead of 5118710, it should be 511-8710. I’d like to add a dash after the user the user inputted 3 digits already in the EditText. The maximum length of the EditText is 7 digits only.

After I figured out the above problem, I’ve got stuck in coding again. When I already inputted 3 digits, it appends dash (that’s what I’d like to happen) but my problem here is that the next 3 digits also appends dash (Like this: 511-871-)… Please help me with this. thanks!

    txt_HomeNo.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

            boolean flag = true;
            String eachBlock[] = txt_HomeNo.getText().toString().split("-");
            for (int i = 0; i < eachBlock.length; i++) {
                if (eachBlock[i].length() > 3) {
                    flag = false;
                }
            }

            if (flag) {

                txt_HomeNo.setOnKeyListener(new OnKeyListener() {

                    @Override
                    public boolean onKey(View v, int keyCode, KeyEvent event) {

                        if (keyCode == KeyEvent.KEYCODE_DEL)
                            keyDel = 1;
                        return false;
                    }
                });

                if (keyDel == 0) {

                    if (((txt_HomeNo.getText().length() + 1) % 4) == 0) {

                        if (txt_HomeNo.getText().toString().split("-").length <= 3) {
                            txt_HomeNo.setText(txt_HomeNo.getText() + "-");
                            txt_HomeNo.setSelection(txt_HomeNo.getText().length());
                        }
                    }
                    a = txt_HomeNo.getText().toString();
                } else {
                    a = txt_HomeNo.getText().toString();
                    keyDel = 0;
                }

            } else {
                txt_HomeNo.setText(a);
            }

        }
How to&Answers:

Implement the following modified addTextChangedListener for txt_HomeNo. The code below is checking if the length of the text entered is 3 and if it is then add the - to it. Not a very robust solution but it works!

txt_HomeNo.addTextChangedListener(new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

        txt_HomeNo.setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {

                if (keyCode == KeyEvent.KEYCODE_DEL)
                    keyDel = 1;
                return false;
            }
        });

        if (keyDel == 0) {
            int len = txt_HomeNo.getText().length();
            if(len == 3) {
                txt_HomeNo.setText(txt_HomeNo.getText() + "-");
                txt_HomeNo.setSelection(txt_HomeNo.getText().length());
            }
        } else {
            keyDel = 0;
        }
    }

    @Override
    public void afterTextChanged(Editable arg0) {
        // TODO Auto-generated method stub
    }

    @Override
    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
        // TODO Auto-generated method stub
    }
});

Answer:

The most straightforward solution is to use PhoneNumberFormattingTextWatcher which will format the number according to the system locale.

XML:

<EditText
    android:id="@+id/phone_number"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="@string/enter_phone_number"
    android:inputType="phone" />

Add addTextChangedListener() in your class:

EditText phoneNumber = (EditText)findViewById(R.id.phone_number);
phoneNumber.addTextChangedListener(new PhoneNumberFormattingTextWatcher());

Answer:

I have a few small changes to the solution of neo108 so it can work with both soft keyboard and hard keyboard, in my code for example the edittext will follow the rule to automatically add ” ” at position 5 and 9.

txtPhone.addTextChangedListener(new TextWatcher() {

        int keyDel;

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            txtPhone.setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
                    if (keyCode == KeyEvent.KEYCODE_DEL) {
                        keyDel = 1;
                    }
                    return false;
                }
            });

            String currentString = txtPhone.getText().toString();
            int currentLength = txtPhone.getText().length();

            if (currentLength == 5 || currentLength == 9) {
                keyDel = 1;
            }

            if (keyDel == 0) {
                if (currentLength == 4 || currentLength == 8) {
                    txtPhone.setText(txtPhone.getText() + " ");
                    txtPhone.setSelection(txtPhone.getText().length());
                }
            } else {
                if (currentLength != 5 && currentLength != 9) {
                    keyDel = 0;
                } else if ((currentLength == 5 || currentLength == 9)
                        && !" ".equals(currentString.substring(currentLength - 1, currentLength))) {
                    txtPhone.setText(currentString.substring(0, currentLength - 1) + " "
                            + currentString.substring(currentLength - 1, currentLength));
                    txtPhone.setSelection(txtPhone.getText().length());
                }
            }
        }

Answer:

I implemented a custom TextWatcher; this handles 10 and 11 digit phone numbers (i.e. 1-555-867-5309 and 555-867-5309). Allows adds, deletions, inserts, mass removal while maintaining proper cursor position.

    public class CustomPhoneTextWatcher implements TextWatcher {

    private final EditText editText;
    private String previousString;

    public CustomPhoneTextWatcher(EditText editText) {
        this.editText = editText;
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        // if the previous editable ends with a dash and new is shorter than previous
        // additionally remove preceding character
        if (previousString != null && previousString.endsWith("-") && editable.toString().length() < previousString.length()) {
            previousString = editable.toString();
            String removedCharacterPriorToDash = editable.toString().substring(0, editable.length() - 1);
            editText.setText(removedCharacterPriorToDash);
            int position = editText.length();
            Editable etext = editText.getText();
            Selection.setSelection(etext, position);
        } else {
            previousString = editable.toString();
            String numericString = StringUtils.removeNonnumeric(editable.toString());
            int stringLength = numericString.length();
            boolean startsWithOne = numericString.startsWith("1");
            numericString = numericString.substring(0, Math.min(stringLength, 10 + (startsWithOne ? 1 : 0)));

            int lastHyphenIndex = 6 + (startsWithOne ? 1 : 0);
            int secondToLastHyphenIndex = 3 + (startsWithOne ? 1 : 0);

            if (stringLength >= lastHyphenIndex) {
                numericString = numericString.substring(0, lastHyphenIndex) + "-" + numericString.substring(lastHyphenIndex, numericString.length());
            }
            if (stringLength >= secondToLastHyphenIndex) {
                numericString = numericString.substring(0, secondToLastHyphenIndex) + "-" + numericString.substring(secondToLastHyphenIndex, numericString.length());
            }
            if (numericString.startsWith("1")) {
                numericString = numericString.substring(0, 1) + "-" + numericString.substring(1, numericString.length());
            }
            if (!numericString.equals(editable.toString())) {
                editText.setText(numericString);
                int position = editText.length();
                Editable etext = editText.getText();
                Selection.setSelection(etext, position);
            }
        }
    }
}

StringUtils.removeNonnumeric(editable.toString()) is a call to this method:

   public static String removeNonnumeric(String text) {
        return text.replaceAll("[^\d]", "");
    }

Answer:

Thanks for the all above answer.

  • The editText.setOnKeyListener() will never invoke when your device has only soft keyboard.
  • If we strictly follow the rule to add “-“, then this code not always show desire result.

    editText.addTextChangedListener(new PhoneNumberFormattingTextWatcher());

but above code is best solution for formatting phone no.

Apart from above this solution, I write a code which work on all types of condition::

phoneNumber.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) {
            if (len > phoneNumber.getText().length() ){
                len--;
                return;
            }
            len = phoneNumber.getText().length();

            if (len == 4 || len== 8) {
                String number = phoneNumber.getText().toString();
                String dash = number.charAt(number.length() - 1) == '-' ? "" : "-";
                number = number.substring(0, (len - 1)) + dash + number.substring((len - 1), number.length());
                phoneNumber.setText(number);
                phoneNumber.setSelection(number.length());
            }
        }
    });

this line of code required to add “-“ on 3rd & 6th position of number.
if (len == 4 || len== 8)

Answer:

Do it yourself by using OnEditTextChangedListener and insert dash by counting number of chars, Counting Chars in EditText Changed Listener

Answer:

import android.text.Editable;
import android.text.Selection;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;

/**
 * Auto-formats a number using -.
 * Ex. 303-333-3333
 * Ex. 1-303-333-3333
 * Doesn't allow deletion of just -
 */
public class PhoneNumberFormattingTextWatcher implements TextWatcher {
    private static final String TAG = "PhoneNumberTextWatcher";

    private final EditText editText;
    private String previousNumber;

    /**
     * Indicates the change was caused by ourselves.
     */
    private boolean mSelfChange = false;

    public PhoneNumberFormattingTextWatcher(EditText editText) {
        this.editText = editText;
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        // if the previous editable ends with a dash and new is shorter than previous
        // additionally remove preceding character
        Log.i(TAG, "Previous String: " + previousNumber);

        //if self change ignore
        if (mSelfChange) {
            Log.i(TAG, "Ignoring self change");
            mSelfChange = false;
            return;
        }

        String phoneNumber = removeNonnumeric(editable.toString());
        int stringLength = phoneNumber.length();

        //empty case
        if(stringLength == 0) {
            mSelfChange = true;
            editText.setText("");
            return;
        }

        boolean startsWithOne = phoneNumber.charAt(0) == '1';
        int maxLength = 10 + (startsWithOne ? 1 : 0);

        //too large
        if(stringLength > maxLength) {
            Log.i(TAG, "String length is greater than max allowed, using previous string: " + previousNumber);
            mSelfChange = true;
            editText.setText(previousNumber);
            Editable etext = editText.getText();
            Selection.setSelection(etext, previousNumber.length());
            return;
        }

        phoneNumber = formatPhoneNumber(phoneNumber);

        if(previousNumber != null && phoneNumber.length() == previousNumber.length()) {
            //user deleting last character, and it is a -
            if(phoneNumber.endsWith("-")) {
                phoneNumber = phoneNumber.substring(0, phoneNumber.length()-2);
            }
        }

        mSelfChange = true;
        previousNumber = phoneNumber;
        editText.setText(phoneNumber);
        Editable etext = editText.getText();
        Selection.setSelection(etext, phoneNumber.length());
    }

    private String formatPhoneNumber(String phoneNumber) {
        int stringLength = phoneNumber.length();
        //check if starts with 1, if it does, dash index is increased by 1
        boolean startsWithOne = phoneNumber.charAt(0) == '1';

        //if the length of the string is 6, add another dash
        int lastHyphenIndex = 6 + (startsWithOne ? 1 : 0);
        if (stringLength >= lastHyphenIndex) {
            phoneNumber = phoneNumber.substring(0, lastHyphenIndex) + "-" + phoneNumber.substring(lastHyphenIndex, phoneNumber.length());
        }
        //if the length of the string is 3, add a dash
        int secondToLastHyphenIndex = 3 + (startsWithOne ? 1 : 0);
        if (stringLength >= secondToLastHyphenIndex) {
            phoneNumber = phoneNumber.substring(0, secondToLastHyphenIndex) + "-" + phoneNumber.substring(secondToLastHyphenIndex, phoneNumber.length());
        }
        //If the number starts with 1, add a dash after 1
        if (phoneNumber.startsWith("1")) {
            phoneNumber = phoneNumber.substring(0, 1) + "-" + phoneNumber.substring(1, phoneNumber.length());
        }

        return phoneNumber;
    }

    private static String removeNonnumeric(String text) {
        return text.replaceAll("[^\d]", "");
    }
}