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


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

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

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

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

18 100

18 ответов:

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

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 только.

EDIT:

установите edittext с android:inputType="number".

спасибо.

в коде Пратика есть небольшая ошибка. Например, если значение равно 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 "";
}

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

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

newVal = newVal.подстрока(0, dstart) + источник.toString ()+ newVal.подстрока(dstart, newVal.длина());

если(newVal.equalsIgnoreCase (" - " ) & & min

int input = целое число.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 "";
}

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

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

в моем понимании мы не можем достичь минимального-максимального ограничения EditText's значение с простым использованием класса 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
            }

        }
    }
}
}

затем в Activity установите InputFilterMax иOnFocusChangeListenerMin до EditText Примечание: Вы можете 2 мин и Макс в onFocusChangeListener.

mQteEditText.setOnFocusChangeListener( new OnFocusChangeListenerMin('20');
mQteEditText.setFilters(new InputFilter[]{new InputFilterMax(getActivity(),'50')});

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

EDIT: обратите внимание, что эта реализация имеет 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;
}

Если вам нужен диапазон с отрицательными числами как -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;
}
}

Я сделал более простой способ установить min / max в 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());
    }
 }

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

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

    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 с text watcher..

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

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

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

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

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

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

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

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

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

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

установите edittext с помощью:

android:inputType="number|numberSigned"

/ / все еще есть некоторые проблемы, но здесь вы можете использовать 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 ...     
             }
         }
      }
 });

чтобы добавить к ответу Пратика, вот модифицированная версия , в которой пользователь может ввести минимум 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;
    }}

добавлено: если(конец==1) min=целое число.parseInt(источник.toString ());

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

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

поэтому я в основном скомпилировал большинство исправлений ошибок, предложенных в ответах на поддержку, а также добавил метод, позволяющий непрерывный ввод чисел вне диапазона в направлении 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 теряет фокус, когда пользователь закончил с ним.

другой вариант-это дезинфекция, когда пользователь нажимает клавишу"готово" /return, но во многих или даже в большинстве случаев это приводит к потере фокуса в любом случае.

тем не менее, закрытие мягкой клавиатуры будет не автоматически расфокусировать элемент. Я уверен, что 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, вы также не столкнетесь с проблемами.)

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

// 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.

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

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

во-первых, создайте 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 edittext = new EditText(context);
editext.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
eInt.setFilters(new InputFilter[]{new MinMaxFilter(min, max)});

Это мой код 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" />

java

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

        }
    });