Есть ли способ определить минимальное и максимальное значение для EditText в Android?

133

Я хочу определить минимальное и максимальное значение для EditText.

Например: если кто-то пытается ввести в него значение месяца, значение должно быть от 1 до 12.

Я могу сделать это с помощью, TextWatcherно я хочу знать, есть ли другой способ сделать это в файле макета или где-то еще.

Изменить: я не хочу ограничивать количество символов. Я хочу ограничить ценность. Например, если я EditTextограничу количество символов месяца w при вводе 12, он примет его, но если я введу 22, он не должен принимать его во время ввода.

mertaydin
источник
Кто-то должен сделать библиотеку / сборник всех этих типов входных фильтров. Тогда каждый сможет работать и тестировать их вместе. Скорее, чем каждый занимается своим делом.
Zapnologica
Используйте этот текстовый фильтр редактирования, чтобы решить вашу проблему. фильтр
Тарас Смакула

Ответы:

286

Сначала сделайте этот класс:

package com.test;

import android.text.InputFilter;
import android.text.Spanned;

public class InputFilterMinMax implements InputFilter {

    private int min, max;

    public InputFilterMinMax(int min, int max) {
        this.min = min;
        this.max = max;
    }

    public InputFilterMinMax(String min, String max) {
        this.min = Integer.parseInt(min);
        this.max = Integer.parseInt(max);
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {   
        try {
            int input = Integer.parseInt(dest.toString() + source.toString());
            if (isInRange(min, max, input))
                return null;
        } catch (NumberFormatException nfe) { }     
        return "";
    }

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

Затем используйте это из своей деятельности:

EditText et = (EditText) findViewById(R.id.myEditText);
et.setFilters(new InputFilter[]{ new InputFilterMinMax("1", "12")});

Это позволит пользователю вводить только значения от 1 до 12 .

РЕДАКТИРОВАТЬ :

Установите текст редактирования с помощью android:inputType="number".

Вы можете найти более подробную информацию на https://www.techcompose.com/how-to-set-minimum-and-maximum-value-in-edittext-in-android-app-development/ .

Спасибо.

Pratik Sharma
источник
1
@мертайдин уверен. попробуйте, а затем дайте мне знать, если вам понадобится моя помощь. Спасибо.
Pratik Sharma
12
Ааа, мне нужна помощь. У меня проблема при записи значения между 1930 и 1999 годами. Когда я пишу 1, он контролирует значение, а 1 - не между 1930 и 1999, поэтому он не принимает его.
mertaydin 08
1
@mertaydin Привет, извини, но я немного занят своей работой. У меня просто есть время, чтобы разобраться в этом, я думаю, мне нужно внести изменения в алгоритм, применяемый в классе фильтра. Я сообщу вам, как только закончу с этим.
Pratik Sharma
1
Некоторые символы из sourceзаменят некоторые символы в dest. Я думаю, вам следует смоделировать замену и получить конечный результат, а затем подтвердить его.
SD
3
@Pratik Sharma, это не работает, когда я ввожу диапазон от 1900 до 2000, вы можете что-нибудь предложить
EminenT
89

В коде Pratik есть небольшая ошибка. Например, если значение равно 10, и вы добавляете 1 в начале, чтобы получить 110, функция фильтрации будет рассматривать новое значение как 101.

См. Ниже исправление этого:

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        // Remove the string out of destination that is to be replaced
        String newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length());
        // Add the new string in
        newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length());
        int input = Integer.parseInt(newVal);
        if (isInRange(min, max, input))
            return null;
    } catch (NumberFormatException nfe) { }
    return "";
}
Zac
источник
Спасибо, это мне очень помогло!
joschplusa 07
4
Я думаю, это яснее imho :String replacement = source.subSequence(start, end).toString(); String newVal = dest.subSequence(0, dstart).toString() + replacement + dest.subSequence(dend, dest.length()).toString();
Sven Jacobs
1
+1. это решение более правильное, чем принятое. Чтобы проверить это, например, попробуйте использовать InputFilterMinMax с включенной опцией selectAllOnFocus и сравните результат.
Sash0k 02
1
Почему бы и нет String newVal= dest.toString().substring(0, dstart) + source.toString().substring(start, end) + dest.toString().substring(dend, dest.toString().length());, выглядит более чистым и понятным.
Шишир Гупта
5
Как упоминал OP @mertaydin в комментарии к ответу @Patrick, у этого решения все еще есть серьезный недостаток, мне интересно, почему о нем не сообщалось: если min==3тогда невозможно ввести любое число, начинающееся с 1 или 2 (например: 15, 23)
Guerneen4
10

Из того, что я видел в решении @ Patrik и добавлении @Zac, предоставленный код все еще имеет большую проблему:

Если min==3тогда невозможно ввести любое число, начинающееся с 1 или 2 (например: 15, 23),
Если min>=10тогда невозможно ввести что-либо, так как каждое число должно начинаться с 1,2,3 ...

Насколько я понимаю, мы не можем достичь ограничения min-max значения an EditTextс помощью простого использования класса InputFilterMinMax, по крайней мере, не для минимального значения, потому что, когда пользователь вводит положительное число, значение увеличивается, и мы можем легко выполнить Тест на лету, чтобы проверить, достиг ли он предела или вышел за пределы диапазона, и заблокировать записи, которые не соответствуют требованиям. Тестирование минимального значения - это другая история, поскольку мы не можем быть уверены, закончил ли пользователь ввод или нет, и поэтому не можем решить, следует ли нам блокировать или нет.

Это не совсем то, что запрашивал OP, но для целей проверки я объединил в своем решении InputFilterдля проверки максимальных значений с OnFocusChangeListenerповторной проверкой минимального значения, когда он EditTextтеряет фокус, предполагая, что пользователь закончил ввод, и это примерно так:

package test;


import android.text.InputFilter;

import android.text.Spanned;

public class InputFilterMax implements InputFilter {

private int max;

public InputFilterMax(int max) {
    this.max = max;
}

public InputFilterMax(String max) {
    this.max = Integer.parseInt(max);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {   
    try {
        String replacement = source.subSequence(start, end).toString(); 

        String newVal = dest.toString().substring(0, dstart) + replacement +dest.toString().substring(dend, dest.toString().length());

        int input = Integer.parseInt(newVal);

        if (input<=max)
            return null;
    } catch (NumberFormatException nfe) { }   
//Maybe notify user that the value is not good      
return "";
}
}

И OnFocusChangeListenerMin

package test;

import android.text.TextUtils;
import android.view.View;
import android.view.View.OnFocusChangeListener;

public class OnFocusChangeListenerMin implements OnFocusChangeListener {

private int min;

public OnFocusChangeListenerMin(int min) {
    this.min = min;
}

public OnFocusChangeListenerMin(String min) {
    this.min = Integer.parseInt(min);
}


@Override
public void onFocusChange(View v, boolean hasFocus) {
    if(!hasFocus) {
        String val = ((EditText)v).getText().toString();
        if(!TextUtils.isEmpty(val)){
            if(Integer.valueOf(val)<min){
                //Notify user that the value is not good
            }

        }
    }
}
}

Затем в деятельности установить InputFilterMaxи OnFocusChangeListenerMinна EditText заметку: Вы можете 2 как минимальное и максимальное в onFocusChangeListener.

mQteEditText.setOnFocusChangeListener( new OnFocusChangeListenerMin('20');
mQteEditText.setFilters(new InputFilter[]{new InputFilterMax(getActivity(),'50')});
Guerneen4
источник
OnFocusChangeListenerMin не работает, ставит все значения с нуля
EminenT
1
Не могли бы вы рассказать немного подробнее? что значит положить все значения с нуля ?
Guerneen4
из кода OnFocusChangeListenerMin должен работать выше 20, как описано в задаче, но он принимает все значения меньше 20, например 0, 1, 2, ------ 19 и т. д.
EminenT
ты нашел какое-нибудь решение?
EminenT
Я использовал OnFoncusChangeListener в целях проверки, в моем случае я отображаю ошибку в EditText, уведомляю пользователя Toast о том, что значение не подходит, и предлагаю ему ввести новое значение. if(Integer.valueOf(val)<min){ //Notify user that the value is not good } Вы можете делать там, что хотите, уведомить user и установите EditText в пустое значение, я не знаю, отвечает ли это на ваш вопрос
Guerneen4
9

Продолжение ответа Пратика и Зака. Зак исправил небольшую ошибку Пратика в своем ответе. Но я заметил, что код не поддерживает отрицательные значения, он выдаст исключение NumberFormatException. Чтобы исправить это и позволить MIN быть отрицательным, используйте следующий код.

Добавьте эту строку (выделенную жирным шрифтом) между двумя другими строками:

newVal = newVal.substring (0, dstart) + source.toString () + newVal.substring (dstart, newVal.length ());

if (newVal.equalsIgnoreCase ("-") && min <0) return null;

int input = Integer.parseInt (newVal);

public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        // Remove the string out of destination that is to be replaced
        String newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length());
        // Add the new string in
        newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length());
        //****Add this line (below) to allow Negative values***// 
        if(newVal.equalsIgnoreCase("-") && min < 0)return null;
        int input = Integer.parseInt(newVal);
        if (isInRange(min, max, input))
            return null;
    } catch (NumberFormatException nfe) {
        nfe.printStackTrace();
    }
    return "";
}
Энтони Б.
источник
5

Если вам нужен диапазон с отрицательными числами, например -90: 90, вы можете использовать это решение.

public class InputFilterMinMax implements InputFilter {

private int min, max;

public InputFilterMinMax(int min, int max) {
    this.min = min;
    this.max = max;
}

public InputFilterMinMax(String min, String max) {
    this.min = Integer.parseInt(min);
    this.max = Integer.parseInt(max);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        String stringInput = dest.toString() + source.toString();
        int value;
        if (stringInput.length() == 1 && stringInput.charAt(0) == '-') {
            value = -1;
        } else {
            value = Integer.parseInt(stringInput);
        }
        if (isInRange(min, max, value))
            return null;
    } catch (NumberFormatException nfe) {
    }
    return "";
}

private boolean isInRange(int min, int max, int value) {
    return max > min ? value >= min && value <= max : value >= max && value <= min;
}
}
Денис Василенко
источник
5

Я расширил код @Pratik Sharmas, чтобы использовать объекты BigDecimal вместо целых чисел, чтобы он мог принимать более крупные числа, и учитывать любое форматирование в EditText, которое не является числом (например, форматирование валюты, то есть пробелы, запятые и точки)

РЕДАКТИРОВАТЬ: обратите внимание, что эта реализация имеет 2 в качестве минимальных значащих цифр, установленных в BigDecimal (см. Константу MIN_SIG_FIG), поскольку я использовал ее для валюты, поэтому всегда было 2 ведущих числа перед десятичной точкой. Измените константу MIN_SIG_FIG, если это необходимо для вашей собственной реализации.

public class InputFilterMinMax implements InputFilter {
private static final int MIN_SIG_FIG = 2;
private BigDecimal min, max;

public InputFilterMinMax(BigDecimal min, BigDecimal max) {
    this.min = min;
    this.max = max;
}

public InputFilterMinMax(String min, String max) {
    this.min = new BigDecimal(min);
    this.max = new BigDecimal(max);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart,
        int dend) {
    try {
        BigDecimal input = formatStringToBigDecimal(dest.toString()
                + source.toString());

        if (isInRange(min, max, input)) {

            return null;
        }
    } catch (NumberFormatException nfe) {

    }
    return "";
}

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

public static BigDecimal formatStringToBigDecimal(String n) {

    Number number = null;
    try {
        number = getDefaultNumberFormat().parse(n.replaceAll("[^\\d]", ""));

        BigDecimal parsed = new BigDecimal(number.doubleValue()).divide(new BigDecimal(100), 2,
                BigDecimal.ROUND_UNNECESSARY);
        return parsed;
    } catch (ParseException e) {
        return new BigDecimal(0);
    }
}

private static NumberFormat getDefaultNumberFormat() {
    NumberFormat nf = NumberFormat.getInstance(Locale.getDefault());
    nf.setMinimumFractionDigits(MIN_SIG_FIG);
    return nf;
}
AndroidNoob
источник
4

Я нашел свой ответ. Уже очень поздно, но я хочу поделиться этим с вами. Реализую этот интерфейс:

import android.text.TextWatcher;


public abstract class MinMaxTextWatcher implements TextWatcher {
    int min, max;
    public MinMaxTextWatcher(int min, int max) {
        super();
        this.min = min;
        this.max = max;
    }

}

А затем реализовать это в своей деятельности таким образом:

private void limitEditText(final EditText ed, int min, int max) {
    ed.addTextChangedListener(new MinMaxTextWatcher(min, max) {
        @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) {
            String str = s.toString();
            int n = 0;
            try {
                n = Integer.parseInt(str);
                if(n < min) {
                    ed.setText(min);
                    Toast.makeText(getApplicationContext(), "Minimum allowed is " + min, Toast.LENGTH_SHORT).show();
                }
                else if(n > max) {
                    ed.setText("" + max);
                    Toast.makeText(getApplicationContext(), "Maximum allowed is " + max, Toast.LENGTH_SHORT).show();
                }
            }
            catch(NumberFormatException nfe) {
                ed.setText("" + min);
                Toast.makeText(getApplicationContext(), "Bad format for number!" + max, Toast.LENGTH_SHORT).show();
            }
        }
    });
}

Это очень простой ответ, расскажите, пожалуйста, лучше.

Наш Макинета
источник
int n = 0; избыточно. Поскольку значение n по умолчанию равно 0.
Кенни
1
Почему int n = 0 здесь избыточен? здесь это локальная переменная, а не переменная экземпляра.
User12111111 09
4

В принятом ответе что-то не так.

int input = Integer.parseInt(dest.toString() + source.toString());

Если я наведу курсор в середину текста, а затем что-нибудь наберу, то приведенный выше оператор даст неверный результат. Например, сначала введите «12», затем введите «0» между 1 и 2, затем приведенный выше оператор даст «120» вместо 102. Я изменил этот оператор на следующие операторы:

String destString = dest.toString();
  String inputString = destString.substring(0, dstart) + source.toString() + destString.substring(dstart);
  int input = Integer.parseInt(inputString);
谭春茂
источник
4

Котлин, если он кому-то нужен (используйте утилиты)

class InputFilterMinMax: InputFilter {
    private var min:Int = 0
    private var max:Int = 0
    constructor(min:Int, max:Int) {
        this.min = min
        this.max = max
    }
    constructor(min:String, max:String) {
        this.min = Integer.parseInt(min)
        this.max = Integer.parseInt(max)
    }
    override fun filter(source:CharSequence, start:Int, end:Int, dest: Spanned, dstart:Int, dend:Int): CharSequence? {
        try
        {
            val input = Integer.parseInt(dest.toString() + source.toString())
            if (isInRange(min, max, input))
                return null
        }
        catch (nfe:NumberFormatException) {}
        return ""
    }
    private fun isInRange(a:Int, b:Int, c:Int):Boolean {
        return if (b > a) c in a..b else c in b..a
    }
}

Затем используйте это из своего класса Kotlin

percentage_edit_text.filters = arrayOf(Utilities.InputFilterMinMax(1, 100))

Этот EditText допускает от 1 до 100.

Затем используйте это из своего XML

android:inputType="number"
Alish
источник
Я использую источник возврата и работаю на меня ==> if (isInRange (min, max, input)) источник возврата
Музафферус
3

Я сделал более простой способ установить минимальное / максимальное значение для Edittext. Я использую арифметическую клавиатуру и работаю по такому методу:

 private int limit(EditText x,int z,int limin,int limax){

    if( x.getText().toString()==null || x.getText().toString().length()==0){
        x.setText(Integer.toString(limin));
        return z=0;
    }
    else{
        z = Integer.parseInt(x.getText().toString());
         if(z <limin || z>limax){
             if(z<10){
                 x.setText(Integer.toString(limin));
                return  z=0;
             }
            else{
                x.setText(Integer.toString(limax));
                return z=limax;
            }

         }
         else
            return z = Integer.parseInt(x.getText().toString());
    }
 }

Метод принимает все ваши значения, но если значение пользователей не соответствует вашим ограничениям, оно будет автоматически установлено на минимальный / максимальный предел. Например, limit limin = 10, limax = 80, если пользователь устанавливает 8, автоматически 10 сохраняется в переменную, а EditText устанавливается на 10.

Argyris
источник
3

Я знаю, что на это уже есть миллион ответов, и один принят. Однако в принятом ответе есть множество ошибок, а большинство остальных просто исправляют одну (или, может быть, две) из них, не расширяя все возможные варианты использования.

Таким образом, я в основном скомпилировал большинство исправлений ошибок, предложенных в ответах службы поддержки, а также добавил метод, позволяющий непрерывно вводить числа за пределами диапазона в направлении 0 (если диапазон не начинается с 0), по крайней мере, до тех пор, пока он уверен, что его больше не может быть в диапазоне. Потому что, чтобы быть ясным, это единственный раз, когда действительно возникают проблемы со многими другими решениями.

Вот исправление:

public class InputFilterIntRange implements InputFilter, View.OnFocusChangeListener {

    private final int min, max;

    public InputFilterIntRange(int min, int max) {
        if (min > max) {
            // Input sanitation for the filter itself
            int mid = max;
            max = min;
            min = mid;
        }
        this.min = min;
        this.max = max;
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {

        // Determine the final string that will result from the attempted input
        String destString = dest.toString();
        String inputString = destString.substring(0, dstart) + source.toString() + destString.substring(dstart);

        // Don't prevent - sign from being entered first if min is negative
        if (inputString.equalsIgnoreCase("-") && min < 0) return null;

        try {
            int input = Integer.parseInt(inputString);
            if (mightBeInRange(input))
                return null;
        } catch (NumberFormatException nfe) {}

        return "";
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {

        // Since we can't actively filter all values
        // (ex: range 25 -> 350, input "15" - could be working on typing "150"),
        // lock values to range after text loses focus
        if (!hasFocus) {
            if (v instanceof EditText) sanitizeValues((EditText) v);
        }
    }

    private boolean mightBeInRange(int value) {
        // Quick "fail"
        if (value >= 0 && value > max) return false;
        if (value >= 0 && value >= min) return true;
        if (value < 0 && value < min) return false;
        if (value < 0 && value <= max) return true;

        boolean negativeInput = value < 0;

        // If min and max have the same number of digits, we can actively filter
        if (numberOfDigits(min) == numberOfDigits(max)) {
            if (!negativeInput) {
                if (numberOfDigits(value) >= numberOfDigits(min) && value < min) return false;
            } else {
                if (numberOfDigits(value) >= numberOfDigits(max) && value > max) return false;
            }
        }

        return true;
    }

    private int numberOfDigits(int n) {
        return String.valueOf(n).replace("-", "").length();
    }

    private void sanitizeValues(EditText valueText) {
        try {
            int value = Integer.parseInt(valueText.getText().toString());
            // If value is outside the range, bring it up/down to the endpoint
            if (value < min) {
                value = min;
                valueText.setText(String.valueOf(value));
            } else if (value > max) {
                value = max;
                valueText.setText(String.valueOf(value));
            }
        } catch (NumberFormatException nfe) {
            valueText.setText("");
        }
    }

}

Обратите внимание, что некоторые варианты ввода невозможно обработать «активно» (т. Е. Пока пользователь вводит их), поэтому мы должны игнорировать их и обрабатывать их после того, как пользователь закончит редактировать текст.

Вот как это можно использовать:

EditText myEditText = findViewById(R.id.my_edit_text);
InputFilterIntRange rangeFilter = new InputFilterIntRange(25, 350);
myEditText.setFilters(new InputFilter[]{rangeFilter});

// Following line is only necessary if your range is like [25, 350] or [-350, -25].
// If your range has 0 as an endpoint or allows some negative AND positive numbers, 
// all cases will be handled pre-emptively.
myEditText.setOnFocusChangeListener(rangeFilter);

Теперь, когда пользователь пытается ввести число ближе к 0, чем позволяет диапазон, произойдет одно из двух:

  1. Если minи maxимеют одинаковое количество цифр, им не будет разрешено вводить его вообще, как только они дойдут до последней цифры.

  2. Если число, выходящее за пределы диапазона, остается в поле, когда текст теряет фокус, он будет автоматически настроен на ближайшую границу.

И, конечно же, пользователю никогда не будет разрешено вводить значение дальше 0, чем позволяет диапазон, и по этой причине такое число не может «случайно» оказаться в текстовом поле.

Известные проблемы?)

  1. Это работает только в том случае, если EditTextобъект теряет фокус, когда пользователь покончил с ним.

Другой вариант - очистка, когда пользователь нажимает клавишу «готово» / «возврат», но во многих или даже в большинстве случаев это все равно приводит к потере фокуса.

Однако закрытие программной клавиатуры не снимает фокус с элемента автоматически. Я уверен, что 99,99% разработчиков Android этого пожелают (и EditTextтакая обработка фокуса на элементах в целом была не такой уж большой проблемой), но пока для этого нет встроенных функций. Самый простой способ, который я нашел, чтобы обойти это, если вам нужно, - это расширить EditTextчто-то вроде этого:

public class EditTextCloseEvent extends AppCompatEditText {

    public EditTextCloseEvent(Context context) {
        super(context);
    }

    public EditTextCloseEvent(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditTextCloseEvent(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            for (InputFilter filter : this.getFilters()) {
                if (filter instanceof InputFilterIntRange)
                    ((InputFilterIntRange) filter).onFocusChange(this, false);
            }
        }
        return super.dispatchKeyEvent(event);
    }
}

Это «обманом» заставит фильтр очистить ввод, даже если представление фактически не потеряло фокус. Если в дальнейшем произойдет потеря фокуса в представлении, очистка ввода сработает снова, но ничего не изменится, поскольку оно уже было исправлено.

закрытие

Уф. Это было много. То, что поначалу казалось тривиально простой задачей, в конечном итоге привело к обнаружению множества уродливых кусочков ванильного Android (по крайней мере, на Java). И еще раз, вам нужно только добавить слушателя и расширить, EditTextесли ваш диапазон каким-то образом не включает 0. (И реально, если ваш диапазон не включает 0, но начинается с 1 или -1, вы также не столкнетесь с проблемами.)

И последнее замечание: это работает только для целых чисел . Конечно, есть способ реализовать его для работы с десятичными знаками ( double, float), но, поскольку ни мне, ни первоначальному пользователю, задающему вопрос, это не нужно, я не особо хочу вдаваться в подробности. Было бы очень просто использовать фильтрацию после завершения вместе со следующими строками:

// Quick "fail"
if (value >= 0 && value > max) return false;
if (value >= 0 && value >= min) return true;
if (value < 0 && value < min) return false;
if (value < 0 && value <= max) return true;

Вам нужно будет только изменить с intна float(или double), разрешить вставку одного .(или ,, в зависимости от страны?) И проанализировать как один из десятичных типов вместо int.

Это в любом случае выполняет большую часть работы, поэтому будет работать очень похоже.

VerumCH
источник
2
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        String prefix = dest.toString().substring(0, dstart);
        String insert = source.toString();
        String suffix = dest.toString().substring(dend);
        String input_string = prefix + insert + suffix;
        int input = Integer.parseInt(input_string);

        if (isInRange(min, max, input) || input_string.length() < String.valueOf(min).length())
            return null;
    } catch (NumberFormatException nfe) { }
    return "";
}

private boolean isInRange(int a, int b, int c) {
    return b > a ? c >= a && c <= b : c >= b && c <= a;
}
jet27
источник
2

Очень простой пример на Котлине:

import android.text.InputFilter
import android.text.Spanned

class InputFilterRange(private var range: IntRange) : InputFilter {

    override fun filter(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int) = try {
        val input = Integer.parseInt(dest.toString() + source.toString())
        if (range.contains(input)) null else ""
    } catch (nfe: NumberFormatException) {
        ""
    }
}
Андрей
источник
1

пожалуйста, проверьте этот код

    String pass = EditText.getText().toString(); 
    if(TextUtils.isEmpty(pass) || pass.length < [YOUR MIN LENGTH]) 
    { 
       EditText.setError("You must have x characters in your txt"); 
        return; 
    }

    //continue processing



edittext.setOnFocusChangeListener( new OnFocusChangeListener() {

       @Override
       public void onFocusChange(View v, boolean hasFocus) {
          if(hasFocus) {
           // USE your code here 
  }

Воспользуйтесь ссылкой ниже, чтобы получить дополнительные сведения о edittext и edittextfilteres с наблюдателем текста.

http://www.mobisoftinfotech.com/blog/android/android-edittext-setfilters-example-numeric-text-field-patterns-and-length-restriction/

itsrajesh4uguys
источник
OP хочет проверить это при вводе значения. Я думаю, вы предоставили решение для сценария после ввода значения
MysticMagicϡ
Я не спрашиваю. Я просто сомневался в вашем ответе, поэтому уточнял.
MysticMagicϡ 08
Я не хочу проверять количество символов. Я думаю, вы пытаетесь проверить счетчик в этом коде: if (TextUtils.isEmpty (pass) || pass.length <[YOUR MIN LENGTH]) Я просто ограничиваю значение, например, для значения месяца, пользователь должен записать значение между 1-12, а не 13,14 и т. Д. Итак, 12,13,14, до 99 - это 2 символа.
mertaydin 08
привет @mertaydin, вы пробовали использовать ссылку, которую я вам предоставил ... посмотрите этот пример ... может быть, это то, что вы хотите. он будет смотреть текст, пока вы вводите ..
itsrajesh4uguys
Хорошо, спасибо, я попробую ваш ответ и ответ @Pratik Sharma.
mertaydin 08
1

Если вас беспокоит только максимальный лимит, просто добавьте строку ниже в

android:maxLength="10" 

Если вам нужно добавить минимальный предел, вы можете сделать так, в этом случае минимальный предел равен 7. Пользователь может вводить символ между минимальным и максимальным пределом (между 8 и 10).

public final static boolean isValidCellPhone(String number){
        if (number.length() < 8 || number.length() >10 ) {
            return false;
        } else {

           return android.util.Patterns.PHONE.matcher(number).matches();
        }
    }

Если вам также нужно ограничить пользователя вводом 01 при запуске, измените условие, подобное этому

if (!(number.startsWith("01")) || number.length() < 8 || number.length() >10 ) {  
.
.
.
}

В конце вызовите метод вроде

   ....else if (!(Helper.isValidMobilePhone(textMobileNo))){
                        Helper.setEditTextError(etMobileNo,"Invalid Mobile Number");
                    }......
Faakhir
источник
2
Это не vlaue, то есть длина
portfoliobuilder
1

@Pratik Sharma

Для поддержки отрицательных чисел добавьте следующий код в метод фильтрации :

package ir.aboy.electronicarsenal;

import android.text.InputFilter;
import android.text.Spanned;

public class InputFilterMinMax implements InputFilter {

  private int min, max;
  int input;

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

  public InputFilterMinMax(String min, String max) {
    this.min = Integer.parseInt(min);
    this.max = Integer.parseInt(max);
  }

  @Override
  public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {

      if ((dest.toString() + source.toString()).equals("-")) {
        source = "-1";
      }

      input = Integer.parseInt(dest.toString() + source.toString());
      if (isInRange(min, max, input))
        return null;

    } catch (NumberFormatException ignored) {
    }
    return "";
  }

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

}

Затем используйте это из своей деятельности:

findViewById(R.id.myEditText).setFilters(new InputFilter[]{ new InputFilterMinMax(1, 12)});

Установите текст редактирования с помощью:

android:inputType="number|numberSigned"
gadolf
источник
0

// все еще есть проблема, но здесь вы можете использовать min, max в любом диапазоне (положительном или отрицательном)

// in filter calss
 @Override
 public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        try {
            // Remove the string out of destination that is to be replaced
            int input;
            String newVal = dest.toString() + source.toString();
            if (newVal.length() == 1 && newVal.charAt(0) == '-') {
                input = min; //allow
            }
            else {
                newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length());
                // Add the new string in
                newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length());
                input = Integer.parseInt(newVal);
            }

            //int input = Integer.parseInt(dest.toString() + source.toString());

            if (isInRange(min, max, input))
                return null;
        } catch (NumberFormatException nfe) {
        }
        return "";
    }

//also the filler must set as below: in the edit createview
// to allow enter number and backspace.
et.setFilters(new InputFilter[]{new InputFilterMinMax(min >= 10 ?  "0" : String.valueOf(min), max >-10 ? String.valueOf(max) :"0" )});



//and at same time must check range in the TextWatcher()
et.addTextChangedListener(new
 TextWatcher() {

      @Override
      public void afterTextChanged (Editable editable)
      {
         String tmpstr = et.getText().toString();
         if (!tmpstr.isEmpty() && !tmpstr.equals("-") ) {
             int datavalue = Integer.parseInt(tmpstr);
             if ( datavalue >= min || datavalue <= max) {
               // accept data ...     
             }
         }
      }
 });
CHTsai
источник
0

Чтобы добавить к ответу Pratik, вот измененная версия, в которой пользователь также может ввести минимум 2 цифры, например, от 15 до 100:

 import android.text.InputFilter;
 import android.text.Spanned;

public class InputFilterMinMax implements InputFilter {

    private int min, max;

    public InputFilterMinMax(int min, int max) {
        this.min = min;
        this.max = max;
    }

    public InputFilterMinMax(String min, String max) {
        this.min = Integer.parseInt(min);
        this.max = Integer.parseInt(max);
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {

        try {
            if(end==1)
                min=Integer.parseInt(source.toString());
            int input = Integer.parseInt(dest.toString() + source.toString());
            if (isInRange(min, max, input))
                return null;
        } catch (NumberFormatException nfe) {
        }
        return "";
    }

    private boolean isInRange(int a, int b, int c) {

        return b > a ? c >= a && c <= b : c >= b && c <= a;
    }}

добавлено: if (end == 1) min = Integer.parseInt (source.toString ());

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

sanjeeb
источник
0

вот как я использовал, он работает для отрицательного числа

Сначала создайте класс MinMaxFIlter.java со следующим кодом:

import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;

/**
* Created by 21 on 4/5/2016.
*/
public class MinMaxFilter implements InputFilter {

private double mIntMin, mIntMax;

public MinMaxFilter(double minValue, double maxValue) {
    this.mIntMin = minValue;
    this.mIntMax = maxValue;
}

public MinMaxFilter(String minValue, String maxValue) {
    this.mIntMin = Double.parseDouble(minValue);
    this.mIntMax = Double.parseDouble(maxValue);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        Boolean isNeg = false;
        String provi = dest.toString() + source.toString();
        if("-".equals(provi.substring(0,1))){
            if(provi.length()>1) {
                provi = provi.substring(1, provi.length());
                isNeg = true;
            }
            else{
                if("".equals(source)){
                    return null;
                }
                return "-";
            }
        }

        double input = Double.parseDouble(provi); 
        if(isNeg){input = input * (-1);}

        if (isInRange(mIntMin, mIntMax, input)) {
            return null;
        }
    } catch (Exception nfe) {}
    return "";
}

private boolean isInRange(double a, double b, double c) {
    if((c>=a && c<=b)){
        return true;
    }
    else{
        return false;
    }
}
}

Затем создайте и установите свой фильтр на свой текст редактирования следующим образом:

EditText edittext = new EditText(context);
editext.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
eInt.setFilters(new InputFilter[]{new MinMaxFilter(min, max)});
maloromano
источник
0

это мой код max = 100, min = 0

XML

<TextView
                    android:id="@+id/txt_Mass_smallWork"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textColor="#000"
                    android:textSize="20sp"
                    android:textStyle="bold" />

Ява

EditText ed = findViewById(R.id.txt_Mass_smallWork);
    ed.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {`

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            if(!charSequence.equals("")) {
                int massValue = Integer.parseInt(charSequence.toString());
                if (massValue > 10) {
                    ed.setFilters(new InputFilter[]{new InputFilter.LengthFilter(2)});
                } else {
                    ed.setFilters(new InputFilter[]{new InputFilter.LengthFilter(3)});
                }
            }
        }

        @Override
        public void afterTextChanged(Editable editable) {

        }
    });
Хоанг
источник
0

Вы можете сделать это с помощью InputFilter. По-видимому, вы можете использовать именно этот интерфейс входного фильтра. Прежде чем вы сделаете это раздражающим способом и создадите новый класс, который расширяет фильтр ввода, вы можете использовать этот ярлык с экземпляром интерфейса внутреннего класса.

Поэтому вы просто делаете это:

EditText subTargetTime = (EditText) findViewById(R.id.my_time);
subTargetTime.setFilters( new InputFilter[] {
                new InputFilter() {
                    @Override
                    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                        int t = Integer.parseInt(source.toString());
                        if(t <8) { t = 8; }
                        return t+"";

                    }
                }
        });

В этом примере я проверяю, больше ли значение EditText, чем 8. Если нет, оно должно быть установлено на 8. Так что, кстати, вам нужно самостоятельно согласовать минимальное максимальное значение или любую другую логику фильтра. Но, по крайней мере, вы можете написать довольно аккуратную и короткую логику фильтра прямо в EditText.

Надеюсь это поможет

Кристофер-Робин Фей Фейзенбе
источник
0

Чтобы определить минимальное значение EditText, я использовал это:

if (message.trim().length() >= 1 && message.trim().length() <= 12) {
  // do stuf
} else {
  // Too short or too long
}
Бонн Богерт
источник
0

Код @ Patrik имеет отличную идею, но с множеством ошибок. @Zac и @Anthony B (решения с отрицательными числами) решили некоторые из них, но в коде @Zac все еще есть 3 ошибки мэра:

1. Если пользователь удаляет все записи в EditText, невозможно ввести какое-либо число снова .. Конечно, этим можно управлять с помощью измененного обработчика EditText в каждом поле, но это сведет на нет красоту использования общего класса InputFilter для каждого поля. EditText в вашем приложении.

2. Если @ Guernee4 говорит, что если, например, min = 3, невозможно ввести любое число, начинающееся с 1.

3. Если, например, min = 0, вы можете ввести сколько угодно нулей, что не будет элегантным результатом. Или также, если неважно, какое минимальное значение, пользователь может поместить курсор в размер слева от первого числа, а также разместить группу ведущих нулей слева, что тоже не элегантно.

Я придумал эти небольшие изменения кода @Zac, чтобы решить эти 3 ошибки. Что касается ошибки №3, мне все еще не удалось полностью удалить все ведущие нули слева; Это всегда может быть один, но 00, 01, 0100 и т. Д. В этом случае более элегантно и корректно, чем 000000, 001, 000100 и т. Д. И т. Д. И т.п.

Вот код:

@Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        try {

            // Using @Zac's initial solution
            String lastVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend);
            String newVal = lastVal.substring(0, dstart) + source.toString() + lastVal.substring(dstart);
            int input = Integer.parseInt(newVal);

            // To avoid deleting all numbers and avoid @Guerneen4's case
            if (input < min && lastVal.equals("")) return String.valueOf(min);

            // Normal min, max check
            if (isInRange(min, max, input)) {

                // To avoid more than two leading zeros to the left
                String lastDest = dest.toString();
                String checkStr = lastDest.replaceFirst("^0+(?!$)", "");
                if (checkStr.length() < lastDest.length()) return "";

                return null;
            }
        } catch (NumberFormatException ignored) {}
        return "";
    }

Хорошего дня!

nnyerges
источник
-1

Вот мой взгляд на ответ Pratik Sharma, Kotlinи Doubleесли он кому-то нужен

class InputFilterMinMax : InputFilter {

private var min: Double = MIN_LIMIT
private var max: Double = MIN_LIMIT

constructor(min: Int, max: Int) {
    this.min = min.toDouble()
    this.max = max.toDouble()
}

constructor(min: String, max: String) {
    this.min = min.toDouble()
    this.max = max.toDouble()
}

constructor(min: Double, max: Double) {
    this.min = min
    this.max = max
}

override fun filter(
    source: CharSequence,
    start: Int,
    end: Int,
    dest: Spanned,
    dstart: Int,
    dend: Int
): CharSequence? {
    try {
        val input = (dest.toString() + source.toString()).toDouble()
        if (isInRange(min, max, input))
            return null
    } catch (nfe: NumberFormatException) {
        Timber.e(nfe)
    }

    return ""
}

private fun isInRange(a: Double, b: Double, c: Double): Boolean {
    return if (b > a) c in a..b else c in b..a
}
}
Варун Барве
источник
Этот входной фильтр неверен, он игнорирует индексы start, end, dstart, dend текста, поэтому, если вы измените текст редактирования, вставив символ посередине, он не будет работать правильно
Radu