'Adding a Dash in the editText automatically in Android

Have a look at my codes:

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

        }

The maximum length of the phone number is only 7. And 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-)... My question is how can I do the codings with the next 4 digit number with having a dash on it. Please help me with this. thanks!



Solution 1:[1]

I think , I have easy solution to doing this, look at attached screenshot

Appending / after 2 and 5 digit to get DOB.

Appending and Deleting both are working without cyclic problem. enter image description here

editeTextDob.addTextChangedListener(new TextWatcher() {
            int prevL = 0;

            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                prevL = dob.getText().toString().length();
            }

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

            }

            @Override
            public void afterTextChanged(Editable editable) {
                int length = editable.length();
                 if ((prevL < length) && (length == 2 || length == 5)) {
                    editable.append("/");
                }
            }
        });

Solution 2:[2]

Use this code This code working for me It will help you

        editText.addTextChangedListener(new TextWatcher() {
        int prevL = 0;
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            prevL = editText.getText().toString().length();
        }

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

        }

        @Override
        public void afterTextChanged(Editable s) {
            int length = s.length();
            if ((prevL < length) && (length == 2 || length == 5)) {
                String data = editText.getText().toString();
                editText.setText(data + "/");
                editText.setSelection(length + 1);


            }

        }
    });

Solution 3:[3]

Improvement on @techroid's answer: (kotlin version)

This will fix on the issue if the character are alphabet, start is always 0 but count and after are correct, while if the character is number, start is correct while the count is always 1, and the after is always 0.

To test the bug:

  • setDashMasking(yourInput, intArrayOf(3))
  • type: asd (this will append dash on after the d, so it will become asd-)

Then try deleting it, it cannot be deleted, unless you input 123, then @techroid's answer will not work.

Below code will be the fix for this issue.

    private fun setDashMasking(input: AppCompatEditText, dashIndexes: IntArray) {
        input.addTextChangedListener(object : TextWatcher {

            private var isFormatting = false
            private var deletingHyphen = false
            private var hyphenStart = 0
            private var deletingBackward = false

            override fun afterTextChanged(editable: Editable) {
                if (isFormatting) return

                isFormatting = true

                // If deleting hyphen, also delete character before or after it
                if (deletingHyphen && hyphenStart > 0) {
                    if (deletingBackward) {
                        if (hyphenStart - 1 < editable.length) {
                            editable.delete(hyphenStart - 1, hyphenStart)
                        }
                    } else if (hyphenStart < editable.length) {
                        editable.delete(hyphenStart, hyphenStart + 1)
                    }
                }

                if (!deletingHyphen &&
                    dashIndexes.contains(editable.toString().length)
                ) {
                    editable.append('-')
                }

                isFormatting = false
            }

            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
                if (isFormatting) return

                // Make sure user is deleting one char, without a selection
                val selStart = Selection.getSelectionStart(s)
                val selEnd = Selection.getSelectionEnd(s)

                if (s.length > 1 // Can delete another character
                    && count - after == 1 // deleting only 1 character
                    && s[selStart - 1] == '-' // a hyphen
                    && selStart == selEnd
                ) { // no selection
                    deletingHyphen = true
                    hyphenStart = selStart - 1
                    // Check if the user is deleting forward or backward
                    deletingBackward = selStart == (selStart - 1) + 1
                } else {
                    deletingHyphen = false
                }
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                listener?.onChanged(s.toString())
            }
        })
    }

Solution 4:[4]

Too late but can help the other people !

  edtMoneyIntMin.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) {
            try {
                int edtInteger = Integer.valueOf(edtMoneyIntMin.getText().toString());
                new DecimalFormat("1,000,000,000");
                String myString = NumberFormat.getInstance().format(edtInteger).replace(",", "/");
                HOUSE_COST_MIN = myString;
                txtMoneyIntMin.setText(myString);
            } catch (NumberFormatException e) {
                e.printStackTrace();
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

Solution 5:[5]

For this kind of request i usually rely on editText Masking technique.

Here is one library that works well:

https://github.com/egslava/edittext-mask

but the one i like the best for handling deleting characters is :

compile 'com.redmadrobot:inputmask:2.3.0'

it has a phone number example in the readme.

Solution 6:[6]

Check Hyphen in onTextChanged Method based on substring of previous text getting from beforeTextChange method. Change condition based on requirement in afterTextChanged Method.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 IshRoid
Solution 2 Dharma lingam
Solution 3 Tenten Ponce
Solution 4 Hadi Note
Solution 5 Edric
Solution 6