InputFilter с CharSequence - отрицательные числа - PullRequest
0 голосов
/ 16 января 2019

У меня есть EdiText с типом ввода: "numberDecimal | number | numberSigned", который должен принимать только значения от -10000 до 10000.

Все работает нормально, за исключением проблемы с отрицательными числами.Допустим, пользователь вводит -123,5 .Все работает нормально, но когда пользователь пытается удалить все, он застревает на -1 (не может удалить дальше).Я изменял значения регулярных выражений с тем же результатом.

Буду очень признателен за любые отзывы об этом или любом другом способе реализации этого.

Примеры проблемы

  • Ввод: -5000
  • Удалить все застревает на: -5
  • Ввод: -0.
  • Удалить все получает значение: -0

Код InputFilter

InputFilter inputFilter = new InputFilter() {
        final int maxDigitsBeforeDecimalPoint = 5;
        final int maxDigitsAfterDecimalPoint = 1;

        @Override
        public CharSequence filter(CharSequence source, int start, int end,
                                   Spanned dest, int dstart, int dend) {
            StringBuilder builder = new StringBuilder(dest);

            builder.replace(dstart, dend, source
                    .subSequence(start, end).toString());
            if (!builder.toString().matches(
                    "(-?([0-9]{1})([0-9]{0," + (maxDigitsBeforeDecimalPoint - 1) + "})?)?(\\.[0-9]{0," + maxDigitsAfterDecimalPoint + "})?"

            )) {
                if (builder.length() == 1 && source.length() == 1 && source.charAt(0) == '-')
                    return "-";
                else if (source.length() == 0)
                    return dest.subSequence(dstart, dend);
                return "";
            }
            if (builder.length() > 0 && builder.toString().charAt(0) == '.') {
                return "";
            }
            if (builder.length() > 1 && builder.toString().charAt(0) == '0' && builder.toString().charAt(1) != '.') {
                return "";
            }
            return null;
        }
    };
    editText.setFilters(new InputFilter[]{new InputFilterMinMax(-10000, 10000), inputFilter});

InputFilterMinMax class

public class InputFilterMinMax implements InputFilter {

    private double min, max;

    private InputFilterMinMax(double min, double max) {
        this.min = min;
        this.max = max;
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        try {
            if (!source.toString().equals("-")) {
                double input = Double.parseDouble(dest.toString() + source.toString());
                if (isInRange(min, max, input))
                    return null;
            } else return  "-";
        } catch (NumberFormatException ignored) {
        }
        return "";
    }

    private boolean isInRange(double a, double b, double c) {
        return b > a ? c >= a && c <= b : c >= b && c <= a;
    }
}
...