web-dev-qa-db-fra.com

Limiter la longueur du texte de EditText dans Android

Quel est le meilleur moyen de limiter la longueur du texte d'un EditText sous Android?

Est-il possible de le faire via XML?

637
hpique

Documentation

Exemple

Android:maxLength="10"
1263
Austin Hanson

utilisez un filtre d'entrée pour limiter la longueur maximale d'une vue de texte.

TextView editEntryView = new TextView(...);
InputFilter[] filterArray = new InputFilter[1];
filterArray[0] = new InputFilter.LengthFilter(8);
editEntryView.setFilters(filterArray);
320
jerry
EditText editText = new EditText(this);
int maxLength = 3;    
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});
189
Emran Hamza

Une note aux personnes qui utilisent déjà un filtre d’entrée personnalisé et aussi veulent limiter la longueur maximale:

Lorsque vous affectez des filtres d'entrée dans le code, tous les filtres d'entrée précédemment définis sont effacés, y compris un ensemble avec Android:maxLength. Je l'ai découvert en essayant d'utiliser un filtre d'entrée personnalisé pour empêcher l'utilisation de certains caractères que nous n'autorisons pas dans un champ de mot de passe. Après avoir défini ce filtre avec setFilters, la longueur maximale n'a plus été observée. La solution a été de définir par programme maxLength et mon filtre personnalisé. Quelque chose comme ça:

myEditText.setFilters(new InputFilter[] {
        new PasswordCharFilter(), new InputFilter.LengthFilter(20)
});
64
goto10
TextView tv = new TextView(this);
tv.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(250) });
36
ramo2712

Pour ceux qui se demandent comment y parvenir, voici ma classe étendue EditText _ EditTextNumeric.

.setMaxLength(int) - définit le nombre maximum de chiffres

.setMaxValue(int) - limite la valeur entière maximale

.setMin(int) - limite la valeur entière minimale

.getValue() - obtenir une valeur entière

import Android.content.Context;
import Android.text.InputFilter;
import Android.text.InputType;
import Android.widget.EditText;

public class EditTextNumeric extends EditText {
    protected int max_value = Integer.MAX_VALUE;
    protected int min_value = Integer.MIN_VALUE;

    // constructor
    public EditTextNumeric(Context context) {
        super(context);
        this.setInputType(InputType.TYPE_CLASS_NUMBER);
    }

    // checks whether the limits are set and corrects them if not within limits
    @Override
    protected void onTextChanged(CharSequence text, int start, int before, int after) {
        if (max_value != Integer.MAX_VALUE) {
            try {
                if (Integer.parseInt(this.getText().toString()) > max_value) {
                    // change value and keep cursor position
                    int selection = this.getSelectionStart();
                    this.setText(String.valueOf(max_value));
                    if (selection >= this.getText().toString().length()) {
                        selection = this.getText().toString().length();
                    }
                    this.setSelection(selection);
                }
            } catch (NumberFormatException exception) {
                super.onTextChanged(text, start, before, after);
            }
        }
        if (min_value != Integer.MIN_VALUE) {
            try {
                if (Integer.parseInt(this.getText().toString()) < min_value) {
                    // change value and keep cursor position
                    int selection = this.getSelectionStart();
                    this.setText(String.valueOf(min_value));
                    if (selection >= this.getText().toString().length()) {
                        selection = this.getText().toString().length();
                    }
                    this.setSelection(selection);
                }
            } catch (NumberFormatException exception) {
                super.onTextChanged(text, start, before, after);
            }
        }
        super.onTextChanged(text, start, before, after);
    }

    // set the max number of digits the user can enter
    public void setMaxLength(int length) {
        InputFilter[] FilterArray = new InputFilter[1];
        FilterArray[0] = new InputFilter.LengthFilter(length);
        this.setFilters(FilterArray);
    }

    // set the maximum integer value the user can enter.
    // if exeeded, input value will become equal to the set limit
    public void setMaxValue(int value) {
        max_value = value;
    }
    // set the minimum integer value the user can enter.
    // if entered value is inferior, input value will become equal to the set limit
    public void setMinValue(int value) {
        min_value = value;
    }

    // returns integer value or 0 if errorous value
    public int getValue() {
        try {
            return Integer.parseInt(this.getText().toString());
        } catch (NumberFormatException exception) {
            return 0;
        }
    }
}

Exemple d'utilisation:

final EditTextNumeric input = new EditTextNumeric(this);
input.setMaxLength(5);
input.setMaxValue(total_pages);
input.setMinValue(1);

Toutes les autres méthodes et attributs qui s'appliquent à EditText fonctionnent bien sûr aussi.

22

En raison de l'observation de goto10, j'ai mis en place le code suivant pour me protéger contre la perte d'autres filtres en définissant la longueur maximale:

/**
 * This sets the maximum length in characters of an EditText view. Since the
 * max length must be done with a filter, this method gets the current
 * filters. If there is already a length filter in the view, it will replace
 * it, otherwise, it will add the max length filter preserving the other
 * 
 * @param view
 * @param length
 */
public static void setMaxLength(EditText view, int length) {
    InputFilter curFilters[];
    InputFilter.LengthFilter lengthFilter;
    int idx;

    lengthFilter = new InputFilter.LengthFilter(length);

    curFilters = view.getFilters();
    if (curFilters != null) {
        for (idx = 0; idx < curFilters.length; idx++) {
            if (curFilters[idx] instanceof InputFilter.LengthFilter) {
                curFilters[idx] = lengthFilter;
                return;
            }
        }

        // since the length filter was not part of the list, but
        // there are filters, then add the length filter
        InputFilter newFilters[] = new InputFilter[curFilters.length + 1];
        System.arraycopy(curFilters, 0, newFilters, 0, curFilters.length);
        newFilters[curFilters.length] = lengthFilter;
        view.setFilters(newFilters);
    } else {
        view.setFilters(new InputFilter[] { lengthFilter });
    }
}
17
Tim Gallagher
//Set Length filter. Restricting to 10 characters only
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH)});

//Allowing only upper case characters
editText.setFilters(new InputFilter[]{new InputFilter.AllCaps()});

//Attaching multiple filters
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_LENGTH), new InputFilter.AllCaps()});
15
Kishore Reddy

J'ai eu ce problème et j'estime qu'il nous manque une méthode bien expliquée pour le faire par programmation sans perdre les filtres déjà définis.

Réglage de la longueur en XML:

Lorsque la réponse acceptée indique correctement, si vous souhaitez définir une longueur fixe pour un EditText que vous ne modifierez plus, définissez-le simplement dans votre XML EditText:

Android:maxLength="10" 

Réglage de la longueur par programme

Pour définir la longueur par programme, vous devez définir un paramètre InputFilter.

Le problème pour Java est le suivant: tous les autres filtres disparaissent (par exemple, maxLines, inputType, etc.). Pour éviter de perdre les filtres précédents, vous devez obtenir ces filtres précédemment appliqués, ajouter maxLength et redéfinir les filtres sur EditText comme suit:

InputFilter[] editFilters = editText.getFilters();
InputFilter[] newFilters = new InputFilter[editFilters.length + 1];
System.arraycopy(editFilters, 0, newFilters, 0, editFilters.length);
newFilters[editFilters.length] = new InputFilter.LengthFilter(10); //the desired length
editText.setFilters(newFilters);

Kotlin Cependant, cela simplifie pour tout le monde, vous devez également ajouter le filtre aux filtres existants, mais vous pouvez y parvenir avec un simple:

editText.filters += InputFilter.LengthFilter(maxLength)
12
Ricardo

Xml

Android:maxLength="10"

Java:

InputFilter[] editFilters = editText.getFilters();
InputFilter[] newFilters = new InputFilter[editFilters.length + 1];
System.arraycopy(editFilters, 0, newFilters, 0, editFilters.length);
newFilters[editFilters.length] = new InputFilter.LengthFilter(maxLength);
editText.setFilters(newFilters);

Kotlin:

editText.filters += InputFilter.LengthFilter(maxLength)
10
João Carlos

Pour cela, vous pouvez également ajouter la définition suivante au fichier XML:

<EditText
    Android:id="@+id/input"
    Android:layout_width="0dp"
    Android:layout_height="wrap_content"
    Android:inputType="number"
    Android:maxLength="6"
    Android:hint="@string/hint_gov"
    Android:layout_weight="1"/>

Cela limitera la longueur maximale du widget EditText à 6 caractères.

8
user2586194

A partir de material.io , vous pouvez utiliser TextInputEditText combiné avec TextInputLayout:

<com.google.Android.material.textfield.TextInputLayout
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    app:counterEnabled="true"
    app:counterMaxLength="1000"
    app:passwordToggleEnabled="false">

    <com.google.Android.material.textfield.TextInputEditText
        Android:id="@+id/edit_text"
        Android:hint="@string/description"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:maxLength="1000"
        Android:gravity="top|start"
        Android:inputType="textMultiLine|textNoSuggestions"/>

</com.google.Android.material.textfield.TextInputLayout>

Vous pouvez configurer un mot de passe EditText avec drawable:

password example

Ou vous pouvez limiter la longueur du texte avec/sans compteur:

counter example

Dépendance:

implementation 'com.google.Android.material:material:1.1.0-alpha02'
4
RonTLV

XML

Android:maxLength="10"

Par programme:

int maxLength = 10;
InputFilter[] filters = new InputFilter[1];
filters[0] = new InputFilter.LengthFilter(maxLength);
yourEditText.setFilters(filters);

Remarque: en interne, EditText & TextView analyse la valeur de Android:maxLength en XML et utilise InputFilter.LengthFilter() pour l'appliquer.

Voir: TextView.Java # L1564

3
nhoxbypass

Cela fonctionne bien ...

Android:maxLength="10"

cela n'acceptera que 10 caractères.

2
Sanjay Kumaar

Il s'agit d'une classe EditText personnalisée qui permet au filtre Longueur de vivre avec d'autres filtres. Merci à la réponse de Tim Gallagher (ci-dessous)

import Android.content.Context;
import Android.text.InputFilter;
import Android.util.AttributeSet;
import Android.widget.EditText;


public class EditTextMultiFiltering extends EditText{

    public EditTextMultiFiltering(Context context) {
        super(context);
    }

    public EditTextMultiFiltering(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditTextMultiFiltering(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setMaxLength(int length) {
        InputFilter curFilters[];
        InputFilter.LengthFilter lengthFilter;
        int idx;

        lengthFilter = new InputFilter.LengthFilter(length);

        curFilters = this.getFilters();
        if (curFilters != null) {
            for (idx = 0; idx < curFilters.length; idx++) {
                if (curFilters[idx] instanceof InputFilter.LengthFilter) {
                    curFilters[idx] = lengthFilter;
                    return;
                }
            }

            // since the length filter was not part of the list, but
            // there are filters, then add the length filter
            InputFilter newFilters[] = new InputFilter[curFilters.length + 1];
            System.arraycopy(curFilters, 0, newFilters, 0, curFilters.length);
            newFilters[curFilters.length] = lengthFilter;
            this.setFilters(newFilters);
        } else {
            this.setFilters(new InputFilter[] { lengthFilter });
        }
    }
}
2
Gal Rom

c'est simple en xml:

Android:maxLength="4"

si vous avez besoin de définir 4 caractères dans le texte d'édition XML, utilisez

<EditText
    Android:id="@+id/edtUserCode"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:maxLength="4"
    Android:hint="Enter user code" />
2
Navadip Patel

J'avais vu beaucoup de bonnes solutions, mais j'aimerais donner une solution plus complète et plus conviviale à mon avis, notamment:

1, longueur limite.
2, Si vous entrez plus, donnez un rappel pour déclencher votre pain grillé.
3, le curseur peut être au milieu ou à la queue.
4, l'utilisateur peut entrer en collant une chaîne.
5, Toujours éliminer l’entrée de débordement et conserver l’origine.

public class LimitTextWatcher implements TextWatcher {

    public interface IF_callback{
        void callback(int left);
    }

    public IF_callback if_callback;

    EditText editText;
    int maxLength;

    int cursorPositionLast;
    String textLast;
    boolean bypass;

    public LimitTextWatcher(EditText editText, int maxLength, IF_callback if_callback) {

        this.editText = editText;
        this.maxLength = maxLength;
        this.if_callback = if_callback;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        if (bypass) {

            bypass = false;

        } else {

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(s);
            textLast = stringBuilder.toString();

            this.cursorPositionLast = editText.getSelectionStart();
        }
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        if (s.toString().length() > maxLength) {

            int left = maxLength - s.toString().length();

            bypass = true;
            s.clear();

            bypass = true;
            s.append(textLast);

            editText.setSelection(this.cursorPositionLast);

            if (if_callback != null) {
                if_callback.callback(left);
            }
        }

    }

}


edit_text.addTextChangedListener(new LimitTextWatcher(edit_text, MAX_LENGTH, new LimitTextWatcher.IF_callback() {
    @Override
    public void callback(int left) {
        if(left <= 0) {
            Toast.makeText(MainActivity.this, "input is full", Toast.LENGTH_SHORT).show();
        }
    }
}));

Ce que j’ai omis de faire, c’est que si l’utilisateur met en surbrillance une partie de l’entrée actuelle et essaie de coller une très longue chaîne, je ne sais pas comment restaurer la surbrillance.

Tels que, longueur maximale est fixée à 10, entrée '12345678' entrée par l'utilisateur, et marquer '345' en surbrillance, et essayer de coller une chaîne de '0000' qui dépassera la limite.

Lorsque j'essaie d'utiliser edit_text.setSelection (start = 2, end = 4) pour restaurer le statut d'origine, le résultat est qu'il insère simplement 2 espaces sous la forme "12 345 678", et non la surbrillance Origin. J'aimerais que quelqu'un résolve cela.

1
hyyou2010

Vous pouvez utiliser Android:maxLength="10" dans EditText (ici, la limite est de 10 caractères).

1
Jocelin

Essayez ceci pour Java par programme:

myEditText(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
0
reza_khalafi