Автоматическое добавление тире в editText в Android

Посмотрите на мои коды:

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

        }

Максимальная длина номера телефона составляет всего 7. И когда я уже ввел 3 цифры, он добавляет тире (это то, что я хотел бы сделать), но моя проблема в том, что следующие 3 цифры также добавляют тире (например, это: 511-871-)... Мой вопрос в том, как я могу сделать кодировку со следующим 4-значным числом с тире на нем. Пожалуйста, помогите мне с этим. Благодарность!


person Community    schedule 07.06.2013    source источник
comment
Привет народ! Большое спасибо за всю вашу помощь! Я просто разобрался с этим с помощью @neo108. :)   -  person    schedule 07.06.2013


Ответы (6)


Попробуй это

@Override
public void afterTextChanged(Editable text) {     


    if (text.length() == 3 || text.length() == 7) {
        text.append('-');
    }


}

или все это

private boolean isFormatting;
private boolean deletingHyphen;
private int hyphenStart;
private boolean deletingBackward;

@Override
public void afterTextChanged(Editable text) {
    if (isFormatting)
        return;

    isFormatting = true;

    // If deleting hyphen, also delete character before or after it
    if (deletingHyphen && hyphenStart > 0) {
        if (deletingBackward) {
            if (hyphenStart - 1 < text.length()) {
                text.delete(hyphenStart - 1, hyphenStart);
            }
        } else if (hyphenStart < text.length()) {
            text.delete(hyphenStart, hyphenStart + 1);
        }
    }
    if (text.length() == 3 || text.length() == 7) {
        text.append('-');
    }

    isFormatting = false;
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    if (isFormatting)
        return;

    // Make sure user is deleting one char, without a selection
    final int selStart = Selection.getSelectionStart(s);
    final int selEnd = Selection.getSelectionEnd(s);
    if (s.length() > 1 // Can delete another character
            && count == 1 // Deleting only one character
            && after == 0 // Deleting
            && s.charAt(start) == '-' // a hyphen
            && selStart == selEnd) { // no selection
        deletingHyphen = true;
        hyphenStart = start;
        // Check if the user is deleting forward or backward
        if (selStart == start + 1) {
            deletingBackward = true;
        } else {
            deletingBackward = false;
        }
    } else {
        deletingHyphen = false;
    }
}
person techroid    schedule 07.06.2013
comment
У меня проблема с Selection.getSelectionStart(s); - person ; 07.06.2013
comment
Привет народ! Большое спасибо за всю вашу помощь! Я просто разобрался с этим с помощью @neo108. :) - person ; 07.06.2013
comment
Ошибка с первым кодом. Попробуйте использовать backspace с этим кодом. - person OhhhThatVarun; 23.09.2019

Я думаю, у меня есть простое решение для этого, посмотрите на прикрепленный скриншот

Добавление / после 2 и 5 цифр для получения DOB.

Добавление и удаление работают без циклических проблем. введите здесь описание изображения

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("/");
                }
            }
        });
person IshRoid    schedule 16.10.2015
comment
В этом есть ошибка. Попробуйте использовать backspace, чтобы удалить текст до 14/02, и введите что-нибудь. Я ожидаю, что / будет добавлено. Но это не так. - person karlingen; 12.04.2021
comment
@karlingen Я посмотрю на это и обновлю свой ответ. Спасибо за отзыв - person IshRoid; 21.05.2021

Используйте этот код Этот код работает для меня Он поможет вам

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


            }

        }
    });
person Dharma lingam    schedule 01.12.2016

Улучшение ответа @techroid: (версия kotlin)

Это устранит проблему, если символ представляет собой алфавит, start всегда равен 0, но count и after верны, а если символ является числом, start является правильным, тогда как count всегда равен 1, а after всегда равен 0.

Чтобы проверить ошибку:

  • setDashMasking(yourInput, intArrayOf(3))
  • введите: asd (это добавит тире после d, поэтому оно станет asd-)

Затем попробуйте удалить его, его нельзя удалить, если вы не введете 123, тогда ответ @techroid не сработает.

Код ниже будет исправлением этой проблемы.

    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())
            }
        })
    }
person Tenten Ponce    schedule 03.06.2020

Слишком поздно, но мы можем помочь другим людям!

  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) {

        }
    });
person Hadi Note    schedule 13.07.2017

Для такого рода запросов я обычно полагаюсь на технику маскирования editText.

Вот одна библиотека, которая хорошо работает:

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

но мне больше всего нравится обрабатывать удаление символов:

compile 'com.redmadrobot:inputmask:2.3.0'

у него есть пример номера телефона в файле readme.

person j2emanue    schedule 06.11.2017