web-dev-qa-db-fra.com

Est-il possible de définir une valeur minimale et maximale pour EditText dans Android?

Je veux définir une valeur minimale et maximale pour une EditText

Par exemple: si une personne essaie d'y entrer une valeur de mois, celle-ci doit être comprise entre 1 et 12.

Je peux le faire en utilisant TextWatcher mais je veux savoir s’il existe un autre moyen de le faire dans un fichier de présentation ou ailleurs.

Edit: Je ne veux pas limiter le nombre de caractères. Je veux limiter la valeur. Par exemple, si je limite le mois EditText w lorsque je saisis 12 caractères, il l’acceptera mais si je saisis 22 caractères, il ne faut pas l’accepter pendant que je saisis.

105
mertaydin

D'abord faire cette classe:

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

Ensuite, utilisez ceci de votre activité:

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

Cela permettra à l'utilisateur d'entrer des valeurs de 1 à 12 uniquement .

MODIFIER :

Définissez votre edittext avec Android:inputType="number".

Merci.

245
Pratik Sharma

Il y a une petite erreur dans le code de Pratik. Par exemple, si une valeur est 10 et que vous ajoutez un 1 au début pour obtenir 110, la fonction de filtre traitera la nouvelle valeur comme 101.

Voir ci-dessous pour un correctif à ceci:

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

Extension de la réponse de Pratik et de Zac. Zac corrigea un petit bug de Pratik dans sa réponse. Mais j'ai remarqué que le code ne supporte pas les valeurs négatives, il va lancer une exception NumberFormatException. Pour résoudre ce problème et permettre au MIN d'être négatif, utilisez le code suivant. 

Ajoutez cette ligne (en gras) entre les deux autres lignes: 

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

if (newVal.equalsIgnoreCase ("-") && min <0) renvoie 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 "";
}
9
Anthony B

De ce que j'ai vu de la solution de @ Patrik et de l'addition de @ Zac, le code fourni a toujours un gros problème:

Si min==3, il est impossible de saisir un nombre commençant par 1 ou 2 (ex: 15, 23)
Si min>=10, il est impossible de saisir quoi que ce soit car chaque numéro doit commencer par 1,2,3 ...

Si je comprends bien, nous ne pouvons pas atteindre la limite min-max de la valeur d'une EditText avec la simple utilisation de la classe InputFilterMinMax, du moins pas pour la valeur min, car lorsque l'utilisateur tape un nombre positif, la valeur augmente et nous pouvons facilement effectuer une test à la volée pour vérifier si la limite est atteinte ou si elle dépasse la plage et bloque les entrées non conformes. Tester la valeur minimale est une autre histoire, car nous ne pouvons pas être sûr que l'utilisateur a fini de taper ou non et ne pouvons donc pas décider s'il faut ou non bloquer.

Ce n'est pas exactement ce que l'OP a demandé, mais aux fins de validation, j'ai combiné dans ma solution une InputFilter pour tester les valeurs maximales, avec une OnFocusChangeListener pour tester à nouveau la valeur minimale lorsque la EditText perd le focus en supposant que l'utilisateur a fini de taper :

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

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

        }
    }
}
}

Ensuite, dans Activité, définissez InputFilterMax et laOnFocusChangeListenerMin sur EditText Remarque: vous pouvez 2 définir les valeurs min et max dans onFocusChangeListener.

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

J'ai étendu le code de @Pratik Sharmas pour qu'il utilise des objets BigDecimal au lieu d'ints afin qu'il puisse accepter des nombres plus grands, et comptabiliser toute mise en forme dans EditText qui n'est pas un nombre (comme une mise en forme monétaire, par exemple des espaces, des virgules et des points)

EDIT: notez que cette implémentation a 2 chiffres minimum significatifs définis sur le BigDecimal (voir la constante MIN_SIG_FIG) comme je l’ai utilisée pour la monnaie, donc il y avait toujours 2 nombres en tête avant le point décimal. Modifiez la constante MIN_SIG_FIG selon vos besoins pour votre propre implémentation. 

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
AndroidNoob

Si vous avez besoin d'une plage avec des nombres négatifs tels que -90: 90, vous pouvez utiliser cette solution. 

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
Denys Vasylenko

Il y a quelque chose qui cloche dans la réponse acceptée.

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

Si je déplace le curseur au milieu du texte, tapez quelque chose, l'instruction ci-dessus produira un résultat erroné .. Par exemple, tapez "12" en premier, puis "0" entre 1 et 2, puis l'instruction mentionnée ci-dessus produire "120" au lieu de 102 . J'ai modifié cette déclaration comme suit:

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

J'ai fait un moyen plus simple de définir un min/max à un Edittext. J'utilise un clavier arithmétique et je travaille avec cette méthode: 

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

La méthode accepte toutes vos valeurs, mais si une valeur d'utilisateurs ne respecte pas vos limites, elle sera automatiquement définie sur la limite minimale/maximale. Pour ex. limit limin = 10, limax = 80 si l'utilisateur définit 8, 10 est automatiquement enregistré dans une variable et EditText est défini sur 10.

3
Argyris

J'ai trouvé ma propre réponse. Il est très tard maintenant mais je veux le partager avec vous ..__ J'implémente cette interface:

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

}

Et puis implémentez-le de cette manière dans votre activité:

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

Ceci est une réponse très simple, s'il y en a une meilleure s'il vous plaît dites-le moi.

2
Nacho García

veuillez vérifier ce code 

    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 
  }

Utilisez le lien ci-dessous pour plus de détails sur edittext et le edittextfilteres avec l'observateur de texte. 

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

2
itsrajesh4uguys
@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
jet27

Si vous êtes uniquement préoccupé par la limite maximale, ajoutez simplement la ligne ci-dessous dans

Android:maxLength="10" 

Si vous devez ajouter une limite minimale, vous pouvez procéder de cette façon. Dans ce cas, la limite minimale est de 7. L'utilisateur est limité à la saisie de caractères entre les limites minimale et maximale (entre 8 et 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();
        }
    }

Si vous devez également empêcher l'utilisateur de saisir 01 au début, modifiez-le si la condition est la suivante. 

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

A la fin de l'appel méthode comme

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

@Pratik Sharma

Pour prendre en chargenombres négatifs, ajoutez le code suivant dans la méthode filter :

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

}

Ensuite, utilisez ceci de votre activité:

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

Définissez votre edittext avec:

Android:inputType="number|numberSigned"
1
gadolf

Je sais qu'il y a déjà un million de réponses à cette question, dont une acceptée. Cependant, la réponse acceptée comporte de nombreux bogues et la plupart des autres bogues résolvent simplement un (ou peut-être deux) d'entre eux, sans développer tous les cas d'utilisation possibles.

Donc, en gros, j'ai compilé la plupart des corrections de bogues suggérées dans les réponses au support, ainsi que l'ajout d'une méthode permettant la saisie continue de nombres en dehors de la plage dans la direction de 0 (si la plage ne commence pas à 0), du moins jusqu'à ce que certain qu'il ne peut plus être dans la gamme. Parce que pour être clair, c'est le seul moment qui cause vraiment des problèmes avec beaucoup d'autres solutions.

Voici le correctif:

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

}

Notez que certains cas de saisie sont impossibles à gérer "activement" (c’est-à-dire que l’utilisateur le saisit). Nous devons donc les ignorer et les traiter une fois que l’utilisateur a terminé la modification du texte.

Voici comment vous pourriez l'utiliser:

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

Désormais, lorsque l'utilisateur essaie de saisir un nombre plus proche de 0 que ne le permet la plage, l'une des deux choses suivantes se produira:

  1. Si min et max ont le même nombre de chiffres, ils ne seront pas autorisés à le saisir une fois qu'ils auront atteint le dernier chiffre.

  2. Si un nombre en dehors de la plage est laissé dans le champ lorsque le texte perd la mise au point, il sera automatiquement ajusté à la limite la plus proche.

Et bien sûr, l'utilisateur ne sera jamais autorisé à entrer une valeur plus éloignée de 0 que la plage ne le permet, et il n'est pas non plus possible qu'un nombre comme celui-ci soit "accidentellement" dans le champ de texte pour cette raison.

Problème (s) connu (s)

  1. Cela ne fonctionne que si la EditText perd le focus lorsque l'utilisateur en a terminé. 

L'autre option est la désinfection lorsque l'utilisateur appuie sur la touche "terminé"/retour, mais dans de nombreux cas, voire dans la plupart des cas, cela entraîne néanmoins une perte de concentration.

Cependant, la fermeture du clavier virtuel pas désactive automatiquement la mise au point de l'élément. Je suis sûr que 99,99% des développeurs Android le souhaiteraient (et que la gestion de la focalisation sur les éléments EditText était moins un bourbier en général), mais il n’existe pour le moment aucune fonctionnalité intégrée. La méthode la plus simple que j'ai trouvée pour contourner ce problème, si vous en avez besoin, est d'étendre EditText à quelque chose comme ceci:

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

Cela "trompera" le filtre pour qu'il désinfecte l'entrée même si la vue n'a pas perdu le focus {en fait. Si, par la suite, la vue perd la mise au point par elle-même, l'assainissement en entrée se déclenchera à nouveau, mais rien ne changera, car elle avait déjà été corrigée.

Fermeture

Ouf. C'était beaucoup. Ce qui à l’origine semblait être un problème assez trivial a fini par mettre au jour de nombreux petits morceaux laids de Vanilla Android (au moins en Java). Et encore une fois, il vous suffit d’ajouter le programme d’écoute et d’étendre EditText si votre plage n’inclut pas 0 de quelque manière que ce soit. (Et de manière réaliste, si votre plage ne comprend pas 0 mais commence à 1 ou -1, vous ne rencontrerez également aucun problème.)

En dernier lieu, cela ne fonctionne que pour ints. Il existe certainement un moyen de le mettre en œuvre pour travailler avec des nombres décimaux (double, float), mais étant donné que ni moi ni le demandeur d'origine n'en avons besoin, je ne souhaite pas vraiment en savoir plus. Il serait très facile d'utiliser simplement le filtrage post-achèvement avec les lignes suivantes:

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

Il vous suffirait de passer de int à float (ou double), d'autoriser l'insertion d'un seul . (ou ,, selon le pays?), Et d'analyser l'un des types décimaux au lieu d'un int.

De toute façon, la plupart du travail s’effectue, ce qui ferait un travail très similaire.

0
VerumCH

Exemple très simple sur 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) {
        ""
    }
}
0
Andrew

Pour définir la valeur minimale de EditText, j'ai utilisé ceci:

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

Vous pouvez le faire avec un InputFilter. Apparemment, il n’ya que cette interface de filtre d’entrée que vous pouvez utiliser. Avant de le faire de manière ennuyeuse pour créer une nouvelle classe qui étend le filtre d’entrée, vous pouvez utiliser ce raccourci avec une instanciation d’interface innerclass.

Par conséquent, vous faites juste ceci:

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

                    }
                }
        });

Dans cet exemple, je vérifie si la valeur de EditText est supérieure à 8. Si ce n'est pas le cas, elle doit être définie sur 8. Vous devez donc vous adapter vous-même au minimum, ou à toute autre logique de filtrage. Mais au moins, vous pouvez écrire la logique de filtrage de manière nette et concise directement dans EditText.

J'espère que cela t'aides

Pour ajouter à la réponse de Pratik, voici une version modifiée dans laquelle l'utilisateur peut entrer au moins 2 chiffres, par exemple de 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;
    }}

ajouté: if (fin == 1) min = Integer.parseInt (source.toString ());

Espérons que cela aide . S'il vous plait, ne votez pas sans raison.

0
sanjeeb

// a encore quelques problèmes mais ici vous pouvez utiliser min, max à n'importe quelle plage

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

c'est mon code 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
Hoàng

voici la façon dont j'ai utilisé, ça marche pour le nombre négatif

Commencez par créer la classe MinMaxFIlter.Java avec le code suivant:

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

Ensuite, créez et définissez votre filtre sur votre edittext comme ceci:

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
maloromano