C'è un modo per definire un valore minimo e massimo per EditText in Android?


133

Voglio definire un valore minimo e massimo per un EditText.

Ad esempio: se una persona tenta di inserire un valore mensile in esso, il valore deve essere compreso tra 1 e 12.

Posso farlo usando TextWatcherma voglio sapere se esiste un altro modo per farlo nel file di layout o altrove.

Modifica: non voglio limitare il conteggio dei personaggi. Voglio limitare il valore. Ad esempio, se limito il mese EditTextcon i caratteri w quando inserisco 12, lo accetterò, ma se inserisco 22 non deve accettarlo mentre entro.


Qualcuno dovrebbe creare una libreria / raccolta di tutti questi tipi di filtri di input. Quindi tutti possono lavorare e testarli insieme. Piuttosto che ogni persona che fa le proprie cose.
Zapnologica,

Utilizzare questo filtro di testo di modifica per risolvere il problema. filtro
Taras Smakula,

Risposte:


286

Prima fai questa lezione:

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

Quindi usa questo dalla tua attività:

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

Ciò consentirà all'utente di immettere solo valori da 1 a 12 .

MODIFICARE :

Imposta il tuo edittext con android:inputType="number".

Puoi trovare maggiori dettagli su https://www.techcompose.com/how-to-set-minimum-and-ma maximum-value- in- edittext- in- android-app-development/ .

Grazie.


1
@mertaydin sicuro. provalo e fammi sapere se hai bisogno del mio aiuto. Grazie.
Pratik Sharma,

12
Aah, ho bisogno di aiuto. Ho un problema durante la scrittura del valore tra il 1930 e il 1999. Quando scrivo 1 controlla il valore e 1 non è tra il 1930 e il 1999, quindi non lo accetta.
Mertaydin,

1
@mertaydin Ehi scusa ma mi sono illuminato un po 'occupato con il mio lavoro. Ho appena avuto un po 'di tempo per esaminare questo, penso di dover apportare modifiche all'algoritmo applicato nella classe del filtro. Ti aggiornerò una volta che avrò finito.
Pratik Sharma,

1
Alcuni caratteri di sourcesostituiranno alcuni caratteri in dest. Penso che dovresti simulare la sostituzione e ottenere il risultato finale, quindi, convalidarlo.
SD

3
@Pratik Sharma, Questo non funziona quando entro l'intervallo dal 1900 al 2000, puoi suggerire qualcosa
EminenT

89

C'è un piccolo errore nel codice di Pratik. Ad esempio, se un valore è 10 e si aggiunge un 1 all'inizio per rendere 110, la funzione filtro tratterà il nuovo valore come 101.

Vedi sotto per una correzione a questo:

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

Grazie, mi ha aiutato molto!
joschplusa,

4
Penso che questo sia più chiaro imho :String replacement = source.subSequence(start, end).toString(); String newVal = dest.subSequence(0, dstart).toString() + replacement + dest.subSequence(dend, dest.length()).toString();
Sven Jacobs,

1
+1. questa soluzione è più corretta di quella accettata. Per verificarlo, ad esempio, provare a utilizzare InputFilterMinMax con l' opzione selectAllOnFocus abilitata e confrontare il risultato.
Sash0k,

1
Perché no String newVal= dest.toString().substring(0, dstart) + source.toString().substring(start, end) + dest.toString().substring(dend, dest.toString().length());, sembra più pulito e chiaro.
Shishir Gupta,

5
Come menzionato da OP @mertaydin in un commento sulla risposta di @Patrick, questa soluzione presenta ancora un grosso difetto, mi chiedo perché non sia stata segnalata: se min==3quindi è impossibile digitare un numero che inizia con 1 o 2 (es: 15, 23)
Guerneen4,

10

Di quello che ho visto della soluzione di @ Patrik e dell'aggiunta di @ Zac, il codice fornito presenta ancora un grosso problema:

Se min==3quindi è impossibile digitare un numero che inizia con 1 o 2 (es: 15, 23)
Se min>=10è impossibile digitare qualsiasi cosa, poiché ogni numero dovrà iniziare con 1,2,3 ...

Secondo la mia comprensione, non possiamo ottenere la limitazione min-max di un EditTextvalore con un semplice uso della classe InputFilterMinMax, almeno non per il valore min, perché quando l'utente sta digitando un numero positivo, il valore aumenta e possiamo facilmente eseguire un test al volo per verificare se ha raggiunto il limite o se è andato oltre l'intervallo e bloccare le voci non conformi. Testare il valore minimo è una storia diversa in quanto non possiamo essere sicuri che l'utente abbia finito di digitare o meno e quindi non possiamo decidere se bloccare o meno.

Non è esattamente ciò che OP ha richiesto, ma ai fini della validazione ho combinato nella mia soluzione un InputFiltertest di valori massimi, con un OnFocusChangeListenernuovo test per il valore minimo quando EditTextil focus perde assumendo che l'utente abbia finito di digitare ed è qualcosa del genere:

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

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

        }
    }
}
}

Quindi, in Attività, impostare il InputFilterMaxe il OnFocusChangeListenerMinda EditText notare: è possibile inserire 2 in min e max onFocusChangeListener.

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

OnFocusChangeListenerMin non funziona, ha messo tutti i valori da zero
EminenT

1
Ti dispiacerebbe dettagliare un po 'di più? cosa intendi per mettere tutti i valori da zero ?
Guerneen4,

dal codice OnFocusChangeListenerMin deve funzionare sopra i 20 come discusso nel problema ma accetta tutti i valori inferiori a 20 come 0, 1, 2, ------ 19 ecc.
EminenT

hai trovato qualche soluzione?
Emin

Ho usato OnFoncusChangeListener a scopo di convalida, nel mio caso visualizzo un errore su EditText avvisa l'utente con un Toast che il valore non è buono e lo invito a inserire un nuovo valore if(Integer.valueOf(val)<min){ //Notify user that the value is not good } Puoi fare quello che vuoi lì, avvisare il utente e imposta EditText su vuoto, non so se questo risponde alla tua domanda
Guerneen4

9

Estensione della risposta di Pratik e Zac. Zac risolse un piccolo bug di Pratik nella sua risposta. Ma ho notato che il codice non supporta valori negativi, genererà una NumberFormatException. Per risolvere questo problema e consentire a MIN di essere negativo, utilizzare il seguente codice.

Aggiungi questa linea (in grassetto) tra le altre due linee:

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

if (newVal.equalsIgnoreCase ("-") && min <0) restituisce 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

Se è necessario un intervallo con numeri negativi come -90: 90, è possibile utilizzare questa soluzione.

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

Ho esteso il codice @Pratik Sharmas per utilizzare oggetti BigDecimal invece di ints in modo che possa accettare numeri più grandi e tenere conto di qualsiasi formattazione in EditText che non sia un numero (come la formattazione della valuta, ad esempio spazi, virgole e punti)

EDIT: nota che questa implementazione ha 2 come cifre minime significative impostate sul BigDecimal (vedi la costante MIN_SIG_FIG) come l'ho usata per la valuta, quindi c'erano sempre 2 numeri iniziali prima del punto decimale. Modifica la costante MIN_SIG_FIG come necessario per la tua implementazione.

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

Ho trovato la mia risposta. È molto tardi adesso, ma voglio condividerlo con te. Realizzo questa interfaccia:

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

}

E quindi implementalo in questo modo all'interno della tua attività:

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

Questa è una risposta molto semplice, per favore, dimmelo.


int n = 0; è ridondante. Poiché il valore predefinito di n è 0.
Kenny Dabiri,

1
Perché int n = 0 è ridondante qui? è una variabile locale e non una variabile di istanza qui.
Utente12111111

4

C'è qualcosa di sbagliato nella risposta accettata.

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

Se sposto il cursore nel mezzo del testo, quindi digito qualcosa, l'istruzione precedente produrrà un risultato errato. Ad esempio, digitare prima "12", quindi digitare "0" tra 1 e 2, quindi l'istruzione sopra menzionata produrrà "120" invece di 102. Ho modificato questa affermazione in istruzioni seguenti:

String destString = dest.toString();
  String inputString = destString.substring(0, dstart) + source.toString() + destString.substring(dstart);
  int input = Integer.parseInt(inputString);

4

Kotlin se qualcuno ne ha bisogno (Usa Utilità)

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

Quindi usa questo dalla tua classe Kotlin

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

Questo EditText consente da 1 a 100.

Quindi usa questo dal tuo XML

android:inputType="number"

Sto usando la fonte di ritorno e lavoro per me ==> if (isInRange (min, max, input)) fonte di ritorno
Muzafferus

3

Ho fatto un modo più semplice per impostare un min / max su un Edittext. Uso la tastiera aritmetica e lavoro con questo metodo:

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

Il metodo accetta tutti i tuoi valori ma se un valore di utenti non aderisce ai tuoi limiti verrà automaticamente impostato sul limite min / max. Per es. limit limin = 10, limax = 80 se l'utente imposta 8, automaticamente 10 viene salvato in una variabile e EditText è impostato su 10.


3

So che ci sono già un milione di risposte a questo, con una accettata. Tuttavia, ci sono numerosi bug nella risposta accettata e la maggior parte degli altri risolve semplicemente uno (o forse due) di essi, senza espandersi a tutti i possibili casi d'uso.

Quindi ho sostanzialmente compilato la maggior parte delle correzioni di bug suggerite nelle risposte di supporto e ho aggiunto un metodo per consentire l'immissione continua di numeri al di fuori dell'intervallo nella direzione 0 (se l'intervallo non inizia da 0), almeno fino a quando non è certo che non può più essere nel range. Perché per essere chiari, questa è l'unica volta che causa davvero problemi con molte altre soluzioni.

Ecco la soluzione:

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

}

Si noti che alcuni casi di input sono impossibili da gestire "attivamente" (cioè, poiché l'utente lo sta inserendo), quindi dobbiamo ignorarli e gestirli dopo che l'utente ha terminato la modifica del testo.

Ecco come potresti usarlo:

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

Ora, quando l'utente tenta di digitare un numero più vicino a 0 di quanto consentito dalla gamma, accadrà una delle due cose:

  1. Se mine maxhanno lo stesso numero di cifre, non sarà possibile immetterle affatto una volta raggiunta la cifra finale.

  2. Se un numero al di fuori dell'intervallo viene lasciato nel campo quando il testo perde lo stato attivo, verrà automaticamente regolato sul limite più vicino.

E, naturalmente, all'utente non sarà mai permesso inserire un valore più lontano da 0 di quanto consentito dalla gamma, né è possibile che un numero come quello sia "accidentalmente" nel campo di testo per questo motivo.

Problemi noti?)

  1. Questo funziona solo se EditTextperde la concentrazione quando l'utente ha finito con esso.

L'altra opzione è la sanificazione quando l'utente preme il tasto "done" / return, ma in molti o anche nella maggior parte dei casi, ciò causa comunque una perdita di messa a fuoco.

Tuttavia, la chiusura della tastiera non disattiverà automaticamente l'elemento. Sono sicuro che il 99,99% degli sviluppatori Android lo vorrebbe (e che la gestione del focus sugli EditTextelementi era meno di un pantano in generale), ma al momento non esiste una funzionalità integrata per questo. Il metodo più semplice che ho trovato per aggirare questo, se necessario, è estendere EditTextqualcosa del genere:

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

Ciò "indurrà" il filtro a disinfettare l'input anche se la vista non ha effettivamente perso la messa a fuoco. Se in seguito la vista dovesse perdere la concentrazione da sola, l'inizializzazione dell'input si innescherà di nuovo, ma nulla cambierà poiché è già stato risolto.

Chiusura

Accidenti. È stato molto. Ciò che originariamente sembrava essere un problema abbastanza banale finì per scoprire molti brutti pezzi di Android vaniglia (almeno in Java). E ancora una volta, devi solo aggiungere il listener ed estenderlo EditTextse il tuo intervallo non include 0 in qualche modo.(E realisticamente, se il tuo intervallo non include 0 ma inizia da 1 o -1, anche tu non incontrerai problemi.)

Come ultima nota, questo funziona solo per ints . C'è sicuramente un modo per implementarlo per lavorare con i decimali ( double, float), ma dal momento che né io né il richiedente originale ne abbiamo bisogno, non voglio approfondire particolarmente. Sarebbe molto semplice utilizzare semplicemente il filtro post-completamento insieme alle seguenti righe:

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

Dovresti solo cambiare da inta float(o double), consentire l'inserimento di un singolo .(o ,, a seconda del paese?) E analizzare come uno dei tipi decimali anziché uno int.

Gestisce comunque la maggior parte del lavoro, quindi funzionerebbe in modo molto simile.


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

Esempio molto semplice su 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) {
        ""
    }
}

1

per favore controlla questo codice

    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 
  }

Usa il link in basso per maggiori dettagli su edittext e sui filtri edittext con watcher di testo.

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


OP vuole convalidarlo quando viene inserito il valore. Penso che tu abbia fornito la soluzione per lo scenario dopo aver inserito il valore
MysticMagicϡ

Non sono l'interrogante. Avevo solo dei dubbi sulla tua risposta, quindi la stavo chiarendo.
MysticMagicϡ

Non voglio controllare il conteggio dei personaggi. Penso che tu stia provando a controllare il conteggio in questo codice: if (TextUtils.isEmpty (pass) || pass.length <[YOUR MIN LENGTH]) Limito solo per il valore, ad esempio per il valore del mese, l'utente deve scrivere il valore tra 1-12 non 13,14 o ecc. Quindi, 12,13,14, fino a quando 99 ha una lunghezza di 2 caratteri.
Mertaydin,

ciao @mertaydin hai provato con il link che ti ho fornito .. vedi quell'esempio .. potrebbe essere quello che vuoi. guarderà il testo mentre si inserisce ..
itsrajesh4uguys

Ok grazie, proverò la tua risposta e la risposta di @Pratik Sharma.
Mertaydin,

1

Se sei preoccupato solo per il limite massimo, aggiungi semplicemente la riga in basso

android:maxLength="10" 

Se devi aggiungere un limite minimo, puoi fare così in questo caso il limite minimo è 7. l'utente è limitato a inserire il carattere tra il limite minimo e massimo (tra 8 e 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();
        }
    }

Se devi anche limitare l'utente a inserire 01 all'avvio, modifica se la condizione è così

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

Alla fine chiama il metodo come

   ....else if (!(Helper.isValidMobilePhone(textMobileNo))){
                        Helper.setEditTextError(etMobileNo,"Invalid Mobile Number");
                    }......

2
Non è vlaue, è lunghezza
portfoliobuilder

1

@Pratik Sharma

Per i numeri negativi di supporto , aggiungere il seguente codice nel metodo di filtro :

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

}

Quindi usa questo dalla tua attività:

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

Imposta il tuo edittext con:

android:inputType="number|numberSigned"

0

// ha ancora qualche problema ma qui puoi usare min, max in qualsiasi intervallo (positivo o negativo)

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

Per aggiungere alla risposta di Pratik, ecco una versione modificata in cui l'utente può inserire almeno 2 cifre, ad esempio da 15 a 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;
    }}

aggiunto: if (end == 1) min = Integer.parseInt (source.toString ());

Spero che questo ti aiuti. gentilmente non sottovalutare senza ragioni.


0

ecco come ho usato, funziona con un numero negativo

Innanzitutto, crea la classe MinMaxFIlter.java con il seguente codice:

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

Quindi, crea e imposta il filtro sul tuo edittext in questo modo:

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

questo è il mio codice 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" />

Giava

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

Puoi farlo con un InputFilter. Apparentemente c'è solo questa interfaccia di filtro di input che puoi usare. Prima di farlo nel modo fastidioso di creare una nuova classe che estende il filtro di input, è possibile utilizzare questo collegamento con un'istanza di interfaccia innerclass.

Quindi fai solo questo:

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+"";

                    }
                }
        });

In questo esempio, controllo se il valore di EditText è maggiore di 8. In caso contrario, deve essere impostato su 8. Quindi, in modo del tutto evidente, è necessario confrontarsi con il minimo massimo o con la logica del filtro da soli. Ma almeno puoi scrivere la logica del filtro abbastanza bene e in breve direttamente nel EditText.

Spero che questo ti aiuti


0

Per definire il valore minimo di EditText, ho usato questo:

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

0

Il codice di @ Patrik ha una bella idea ma con molti bug. @Zac e @Anthony B (soluzioni con numeri negativi) hanno risolto alcuni di essi, ma il codice di @ Zac ha ancora 3 bug principali:

1. Se l'utente elimina tutte le voci nell'EditText, è impossibile digitare nuovamente qualsiasi numero. Naturalmente questo può essere controllato usando un listener modificato EditText su ciascun campo, ma cancellerà la bellezza dell'uso di una classe InputFilter comune per ogni Modifica testo nella tua app.

2. Has @ Guernee4 dice, se per esempio min = 3, è impossibile digitare qualsiasi numero che inizia con 1.

3. Se ad esempio min = 0, puoi digitare ha molti zeri che desideri, che non sia elegante il risultato. Oppure, se non importa quale sia il valore minimo, l'utente può posizionare il cursore nella dimensione sinistra del primo numero, un posto un gruppo di zeri iniziali a sinistra, anche non elegante.

Sono arrivato con questi piccoli cambiamenti del codice di @ Zac per risolvere questi 3 bug. Per quanto riguarda il bug n. 3, non sono ancora riuscito a rimuovere completamente tutti gli zeri iniziali a sinistra; Può sempre essere uno, ma un 00, 01, 0100 ecc. In quel caso, è più elegante e valido di un 000000, 001, 000100, ecc. Ecc. Eccetera.

Ecco il codice:

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

Buona giornata!


-1

Ecco la mia opinione sulla risposta di Pratik Sharma per Kotline Doublese qualcuno ne ha bisogno

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

Questo filtro di input è errato, ignora gli indici di inizio, fine, avvio, dend del testo, quindi se si modifica il testo di modifica inserendo un carattere nel mezzo non funzionerà correttamente
Radu
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.