Qual è il modo migliore per limitare la lunghezza del testo di EditText in Android


702

Qual è il modo migliore per limitare la lunghezza del testo di un EditTextin Android?

C'è un modo per farlo tramite XML?


1
Volevo impostare il numero massimo di caratteri per il mio EditText. All'inizio non era ovvio che il limite di lunghezza del testo fosse la stessa cosa. (Solo una nota per un altro viaggiatore confuso).
Katedral Pillon,

La risposta corretta è qui : stackoverflow.com/a/19222238/276949 . Questa risposta limita la lunghezza E impedisce a un buffer di riempirsi continuamente dopo aver raggiunto il limite, consentendo quindi al tasto backspace di funzionare correttamente.
Martin Konecny,

Risposte:


1381

Documentazione

Esempio

android:maxLength="10"

26
D'oh! Mi è successa la stessa cosa. Stavo guardando il codice e non esiste un metodo setMaxLength.
hpique

1
cosa fa il Check qui? Si collega a questa pagina.
che cosa è dormire

5
@Vincy, hai sbagliato. La maxLengthproprietà funziona ancora.
ashishduh,

6
Tieni presente che android:maxLengthequivale a InputFilter.LengthFilter, quindi quando modifichi a livello di codice il suo filtro, hai modificato anche il suo filtro XML.
5

20
Alle persone che affermano che non funziona, tieni presente che la chiamata setFilterssmetterà di android:maxLengthfunzionare, perché sovrascrive il filtro impostato dall'XML. In altre parole, se si impostano filtri a livello di codice, è necessario impostarli tutti a livello di codice.
Ian Newson,

339

utilizzare un filtro di input per limitare la lunghezza massima di una vista di testo.

TextView editEntryView = new TextView(...);
InputFilter[] filterArray = new InputFilter[1];
filterArray[0] = new InputFilter.LengthFilter(8);
editEntryView.setFilters(filterArray);

5
Questo è molto utile se qualcuno ne ha già fatto un po ' InputFilter. Sovrascrive android:maxlengthnel file xml, quindi dobbiamo aggiungere in LengthFilterquesto modo.
Seblis,

Penso che la tua risposta sia la migliore, dato che è più dinamica, +1
Muhannad A.Alhariri,

197
EditText editText = new EditText(this);
int maxLength = 3;    
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});

Questo è simile al modo in cui Android lo fa con l'xml.
Nicolas Tyler,

4
Come posso impostare la lunghezza minima?
Akhila Madari,

@AkhilaMadari, probabilmente con TextWatcher.
CoolMind,

65

Una nota per le persone che stanno già utilizzando un filtro di input personalizzato e desiderano anche limitare la lunghezza massima:

Quando si assegnano i filtri di input nel codice, tutti i filtri di input impostati in precedenza vengono cancellati, incluso un set con android:maxLength. L'ho scoperto quando ho tentato di utilizzare un filtro di input personalizzato per impedire l'uso di alcuni caratteri che non è consentito in un campo password. Dopo aver impostato quel filtro con setFilters, la lunghezza massima non è stata più osservata. La soluzione era impostare maxLength e il mio filtro personalizzato insieme a livello di codice. Qualcosa come questo:

myEditText.setFilters(new InputFilter[] {
        new PasswordCharFilter(), new InputFilter.LengthFilter(20)
});

5
È possibile recuperare prima i filtri esistenti come, InputFilter []istingFilters = editText.getFilters (); Quindi aggiungi il filtro insieme a questi filtri esistenti
subair_a

39
TextView tv = new TextView(this);
tv.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(250) });

7
Certo, solo per Android
VAdaihiep,

27

Ho avuto questo problema e ritengo che ci manchi un modo ben spiegato per farlo programmaticamente senza perdere i filtri già impostati.

Impostazione della lunghezza in XML:

Come afferma correttamente la risposta accettata, se si desidera definire una lunghezza fissa per un EditText che non si modificherà ulteriormente in futuro, è sufficiente definire nel proprio XML EditText:

android:maxLength="10" 

Impostazione della lunghezza a livello di codice

Per impostare la lunghezza a livello di codice, è necessario impostarla tramite un InputFilter. Ma se crei un nuovo InputFilter e lo imposti su EditTextperderai tutti gli altri filtri già definiti (ad es. MaxLines, inputType, ecc.) Che potresti aver aggiunto tramite XML o programmaticamente.

Quindi questo è SBAGLIATO :

editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});

Per evitare di perdere i filtri aggiunti in precedenza, è necessario ottenere quei filtri, aggiungere quello nuovo (maxLength in questo caso) e ripristinare i filtri EditTextcome segue:

Giava

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 tuttavia ha reso più facile per tutti, devi anche aggiungere il filtro a quelli già esistenti ma puoi farlo con un semplice:

editText.filters += InputFilter.LengthFilter(maxLength)

23

Per chiunque si stia chiedendo come raggiungere questo obiettivo, ecco la mia EditTextclasse estesa EditTextNumeric.

.setMaxLength(int) - imposta il numero massimo di cifre

.setMaxValue(int) - limitare il valore intero massimo

.setMin(int) - limitare il valore intero minimo

.getValue() - ottiene il valore intero

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

Esempio di utilizzo:

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

EditTextOvviamente funzionano anche tutti gli altri metodi e attributi applicabili .


1
Sarebbe meglio se lo aggiungessimo nel layout xml. Sto ottenendo un errore con questo quando uso xml Causato da: android.view.InflateException: riga di file XML binario # 47: errore durante il gonfiaggio della classe com.passenger.ucabs.utils.EditTextNumeric
Shihab Uddin

@Martynas Hai riscontrato lo stesso errore di Shihab_returns qualsiasi soluzione?
Pranaysharma,

17

A causa dell'osservazione di goto10, ho messo insieme il seguente codice per proteggermi dal perdere altri filtri con l'impostazione della lunghezza massima:

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

3
Potresti voler aggiornare leggermente il codice. L'array allocato deve essere curFilters.length + 1 in dimensioni e dopo aver creato newFilters, non hai impostato "this" sull'array appena allocato. InputFilter newFilters [] = new InputFilter [curFilters.length + 1]; System.arraycopy (curFilters, 0, newFilters, 0, curFilters.length); this.setFilters (newFilters);
JavaCoderEx

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

12

Xml

android:maxLength="10"

Giava:

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)

8

Un altro modo per ottenere ciò è aggiungendo la seguente definizione al file 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"/>

Ciò limiterà la lunghezza massima del EditTextwidget a 6 caratteri.


6

Da material.io , è possibile utilizzare in TextInputEditTextcombinazione con 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>

È possibile configurare una password EditText con drawable:

esempio di password

Oppure puoi limitare la lunghezza del testo con / senza contatore:

contro esempio

Dipendenza:

implementation 'com.google.android.material:material:1.1.0-alpha02'

6

XML

android:maxLength="10"

livello di programmazione:

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

Nota: internamente, EditText e TextView analizzano il valore di android:maxLengthin XML e lo utilizzano InputFilter.LengthFilter()per applicarlo.

Vedi: TextView.java # L1564


2

Questa è una classe EditText personalizzata che consente al filtro Lunghezza di vivere insieme ad altri filtri. Grazie alla risposta di Tim Gallagher (sotto)

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

in modo semplice in XML:

android:maxLength="4"

se hai bisogno di impostare 4 caratteri in xml edit-text, usa questo

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

2

Funziona bene ...

android:maxLength="10"

questo accetterà solo 10caratteri.


2

Prova questo per Java a livello di codice :

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

1
Hai dimenticato di chiamare il metodo, quindi dovrebbe apparire come myEditText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
segue

1

Avevo visto molte buone soluzioni, ma mi piacerebbe dare una soluzione che ritengo più completa e intuitiva, che include:

1, lunghezza limite.
2, se inserisci di più, dai un callback per attivare il tuo brindisi.
3, il cursore può essere al centro o alla coda.
4, l'utente può inserire incollando una stringa.
5, Elimina sempre l'input di overflow e mantiene 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();
        }
    }
}));

Quello che non sono riuscito a fare è, se l'utente evidenzia una parte dell'input corrente e prova a incollare una stringa molto lunga, non so come ripristinare l'evidenziazione.

Ad esempio, la lunghezza massima è impostata su 10, l'utente immesso '12345678' e contrassegna '345' come punto culminante e prova a incollare una stringa di '0000' che supererà la limitazione.

Quando provo a usare edit_text.setSelection (inizio = 2, fine = 4) per ripristinare lo stato dell'origine, il risultato è che inserisco solo 2 spazi come '12 345 678 ', non l'evidenziazione dell'origine. Vorrei che qualcuno lo risolvesse.


1

È possibile utilizzare android:maxLength="10"in EditText. (Qui il limite è massimo di 10 caratteri)


0

Kotlin:

edit_text.filters += InputFilter.LengthFilter(10)

ZTE Blade A520ha uno strano effetto. Quando si digitano più di 10 simboli (ad esempio, 15), vengono EditTextvisualizzati i primi 10, ma altri 5 non sono visibili e non accessibili. Ma quando elimini i simboli con Backspace, elimina prima i 5 simboli giusti e poi rimuove i rimanenti 10. Per superare questo comportamento usa una soluzione :

android:inputType="textNoSuggestions|textVisiblePassword"
android:maxLength="10"

o questo:

android:inputType="textNoSuggestions"

o questo, se vuoi avere suggerimenti:

private class EditTextWatcher(private val view: EditText) : TextWatcher {
    private var position = 0
    private var oldText = ""

    override fun afterTextChanged(s: Editable?) = Unit

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        oldText = s?.toString() ?: ""
        position = view.selectionStart
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        val newText = s?.toString() ?: ""
        if (newText.length > 10) {
            with(view) {
                setText(oldText)
                position = if (start > 0 && count > 2) {
                    // Text paste in nonempty field.
                    start
                } else {
                    if (position in 1..10 + 1) {
                        // Symbol paste in the beginning or middle of the field.
                        position - 1
                    } else {
                        if (start > 0) {
                            // Adding symbol to the end of the field.
                            start - 1
                        } else {
                            // Text paste in the empty field.
                            0
                        }
                    }
                }
                setSelection(position)
            }
        }
    }
}

// Usage:
editTextWatcher = EditTextWatcher(view.edit_text)
view.edit_text.addTextChangedListener(editTextWatcher)

0

in modo semplice in XML:

android:maxLength="@{length}"

per impostarlo a livello di programmazione è possibile utilizzare la seguente funzione

public static void setMaxLengthOfEditText(EditText editText, int length) {
    InputFilter[] filters = editText.getFilters();
    List arrayList = new ArrayList();
    int i2 = 0;
    if (filters != null && filters.length > 0) {
        int length = filters.length;
        int i3 = 0;
        while (i2 < length) {
            Object obj = filters[i2];
            if (obj instanceof LengthFilter) {
                arrayList.add(new LengthFilter(length));
                i3 = 1;
            } else {
                arrayList.add(obj);
            }
            i2++;
        }
        i2 = i3;
    }
    if (i2 == 0) {
        arrayList.add(new LengthFilter(length));
    }
    if (!arrayList.isEmpty()) {
        editText.setFilters((InputFilter[]) arrayList.toArray(new InputFilter[arrayList.size()]));
    }
}
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.