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

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

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

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

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

Ответ 1

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

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

Спасибо.

Ответ 2

В коде 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 "";
}

Ответ 3

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

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

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

, если (newVal.equalsIgnoreCase( "-" ) & min < 0) возвращает 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 "";
}

Ответ 4

Я расширил код @Pratik Sharmas, чтобы использовать объекты BigDecimal вместо int, чтобы он мог принимать большие числа и учитывать любое форматирование в 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;
}

Ответ 5

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

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

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

Это не совсем то, что запрошено 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 Примечание: вы можете использовать оба значения min и max в OnFocusChangeListener.

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

Ответ 6

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

Ответ 7

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

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

Ответ 8

Я сделал более простой способ установить 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.

Ответ 9

проверьте этот код

    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/

Ответ 10

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

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

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

Ответ 11

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

Ответ 12

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

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

Ответ 13

@Pratik Шарма

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

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"

Ответ 14

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

Ответ 15

Чтобы добавить к ответу Pratik, здесь приведена модифицированная версия, в которой пользователь может ввести не менее двух цифр, например, от 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)             мин = Integer.parseInt(source.toString());

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

Ответ 16

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

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

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

Ответ 17

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

Сначала создайте класс 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)});

Ответ 18

это мой код 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) {

        }
    });

Ответ 19

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

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

Ответ 20

Вы можете сделать это с помощью 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) {
                        float t = Float.parseFloat(subTargetTime.getText().toString());
                        if(t <8) { t = 8; }
                        return t+"";
                    }
                }
        });

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

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

Ответ 21

это простой способ в xml:

android:maxLength="4"

Если вам нужно установить 4 символа в текстовом редакторе xml, используйте это:

<EditText
    android:id="@+id/tv_date_time"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:maxLength="4"/>