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


133

Я хочу визначити значення min та max для EditText.

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

Я можу це зробити, використовуючи, TextWatcherале я хочу знати, чи є інший спосіб зробити це у файлі компонування чи в іншому місці.

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


Хтось повинен створити бібліотеку / колекцію всіх цих типів вхідних фільтрів. Тоді кожен може працювати та протестувати їх разом. Замість того, щоб кожна людина робила свою справу.
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/ .

Дякую.


1
@mertaydin впевнений. спробуйте, тоді дайте мені знати, якщо вам потрібна моя допомога. Дякую.
Пратік Шарма

12
Ах, мені потрібна допомога. У мене є проблема, коли значення writig між 1930 і 1999 роками. Коли я пишу 1, це керує значенням, а 1 - не між 1930 і 1999 роками, тому воно не приймає.
мертайдин

1
@mertaydin Ей вибачте, але я засвітився трохи зайнятим своєю роботою. У мене просто було певний час, щоб розібратися в цьому, я думаю, що мені потрібно внести зміни в алгоритм, застосований у класі фільтру. Я оновлю вас, як тільки я зроблю з цим.
Пратік Шарма

1
Деякі символи з sourceзамінять деякі символи в dest. Я думаю, ви повинні імітувати заміну та отримати кінцевий результат, а потім перевірити її.
СД

3
@Pratik Sharma, Це не спрацьовує, коли я входжу в діапазон з 1900 по 2000 рік, можете запропонувати щось
EminenT

89

У коді Пратіка є невелика помилка. Наприклад, якщо значення дорівнює 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 "";
}

Спасибі це мені дуже допомогло!
joschplusa

4
Я думаю , що це ясніше имхо :String replacement = source.subSequence(start, end).toString(); String newVal = dest.subSequence(0, dstart).toString() + replacement + dest.subSequence(dend, dest.length()).toString();
Свен Jacobs

1
+1. це рішення більш правильне, ніж прийняте. Щоб перевірити це, наприклад, спробуйте використовувати InputFilterMinMax з включеною опцією selectAllOnFocus та порівняйте результат.
Sash0k

1
Чому ні String newVal= dest.toString().substring(0, dstart) + source.toString().substring(start, end) + dest.toString().substring(dend, dest.toString().length());, виглядає більш чисто і чітко.
Шишир Гупта

5
Як згадував ОП @mertaydin у коментарі до відповіді @Patrick, це рішення все ще має основний недолік, мені цікаво, чому про нього не повідомлялося: Якщо min==3тоді неможливо набрати будь-яке число, починаючи з 1 або 2 (наприклад: 15, 23)
Guerneen4

10

З того, що я бачив у вирішенні рішення @ Patrik та доповнення @ Zac, наданий код все ще має велику проблему:

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

На моє розуміння, ми не можемо досягти обмеження мінімальної максимальної EditTextвеличини s простим використанням класу InputFilterMinMax, принаймні, не для мінімального значення, оскільки, коли користувач набирає додатне число, значення зростає, і ми можемо легко виконати тест на ходу, щоб перевірити, чи досягнуто ліміту чи вийшов за межі діапазону, і заблокувати записи, які не відповідають. Тестування мінімального значення - це інша історія, тому що ми не можемо бути впевнені, чи закінчив користувач вводити чи ні, і тому не можемо вирішити, чи слід блокувати чи ні.

Це не зовсім те, що вимагало ОП, але для цілей перевірки я поєднав у своєму рішенні 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')});

OnFocusChangeListenerMin не працює, він ставить усі значення з нуля
EminenT

1
Ви б не хотіли деталізувати трохи більше? що ти маєш на увазі поставити всі значення з нуля ?
Guerneen4

з коду OnFocusChangeListenerMin повинен працювати вище 20, як обговорювалося в проблемі, він приймає всі значення менше 20, як 0, 1, 2, ------ 19 і т.д.
EminenT

ви знайшли якесь рішення?
EminenT

Я використовував OnFoncusChangeListener для перевірки, в моєму випадку я показую помилку на EditText, повідомляю користувача про тост, що значення не є гарним, і запрошую його ввести нове значення. if(Integer.valueOf(val)<min){ //Notify user that the value is not good } Ви можете робити все, що вам потрібно, сповістити користувача та встановіть EditText порожнім, я не знаю, чи відповідає це на ваше запитання
Guerneen4

9

Подовження відповіді Пратіка та Зака. Зак виправив невеличку помилку Пратіка у своїй відповіді. Але я помітив, що код не підтримує негативні значення, він викине 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 "";
}

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 замість 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;
}

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 тут зайвий? його локальна змінна, а не змінна інстанція тут.
Користувач12111111

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

Потім використовуйте це з вашого класу Котлін

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

Цей EditText дозволяє від 1 до 100.

Потім використовуйте це зі свого XML

android:inputType="number"

Я використовую джерело повернення і працюю для мене ==> if (isInRange (min, max, input)) return source
Muzafferus

3

Я зробив більш простий спосіб встановити min / max для редагування тексту. Я використовую арифметичну клавіатуру, і я працюю з цим методом:

 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.


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, ви також не зіткнетеся з проблемами.)

Як остання примітка, це працює лише для ints . Звичайно, існує спосіб реалізувати його для роботи з десятковою комою ( 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.

Це в будь-якому випадку справляється з більшою частиною роботи, так що це буде працювати дуже аналогічно.


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

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/


ОП хоче перевірити його під час введення значення. Я думаю, ви запропонували рішення для сценарію після введення значення
MysticMagicϡ

Я не запитувач. Я просто сумнівався стосовно вашої відповіді, тому я уточнював її.
MysticMagicϡ

Я не хочу перевіряти кількість символів. Я думаю, ви намагаєтеся перевірити кількість у цьому коді: якщо (TextUtils.isEmpty (пропуск) || pass.length <[YOUR MIN LENGTH]) Я просто обмежую значення, наприклад, для місячного значення, користувач повинен записати значення між 1-12 не 13,14, і т. Д. Отже, 12,13,14, поки 99 не дорівнює 2 символам.
мертайдин

привіт @mertaydin Ви спробували зі посиланням, яке я вам надав .. дивіться цей приклад .. може бути те, що ви хочете. він буде дивитися текст, поки ви вводите ..
itsrajesh4uguys

Добре дякую, я спробую вашу відповідь і відповідь @Pratik Sharma.
мертайдин

1

Якщо вас турбує лише максимальне обмеження, просто додайте нижче рядка в

android:maxLength="10" 

Якщо вам потрібно додати мінімальний ліміт, ви можете зробити так, як у цьому випадку мінімум обмеження становить 7. Користувачам заборонено вводити символ між min та max limit (від 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");
                    }......

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"

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

0

Щоб додати відповідь Пратіка, ось модифікована версія, де користувач може також ввести мінімум 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 ());

Сподіваюся, це допомагає. люб’язно не дайте довідки без причин.


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

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

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

        }
    });

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. Отже, належно вам потрібно скласти мінімум max або будь-яку логіку фільтра самостійно. Але принаймні, ти можеш записати логіку фільтра досить акуратно і коротко безпосередньо в EditText.

Сподіваюся, це допомагає


0

Для визначення мінімального значення EditText я використав це:

if (message.trim().length() >= 1 && message.trim().length() <= 12) {
  // do stuf
} else {
  // Too short or too long
}

0

@ Код Патріка має гарну ідею, але з великою кількістю помилок. @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 "";
    }

Гарного дня!


-1

Ось мій погляд на відповідь Пратіка Шарма 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
}
}

Цей вхідний фільтр невірний, він ігнорує початок, кінець, dstart, індекси денду тексту, тому якщо змінити текст редагування, вставивши в середину символ, він не працюватиме правильно
Раду
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.