Was ist der beste Weg, um die Textlänge von EditText in Android zu begrenzen?

702

Was ist der beste Weg, um die Textlänge eines EditTextin Android zu begrenzen ?

Gibt es eine Möglichkeit, dies über XML zu tun?

hpique
quelle
1
Ich wollte die maximale Anzahl von Zeichen für meinen EditText festlegen. Anfangs war es nicht offensichtlich, dass die Beschränkung der Textlänge dasselbe war. (Nur eine Notiz für einen anderen verwirrenden Reisenden).
Katedral Pillon
Die richtige Antwort finden Sie hier : stackoverflow.com/a/19222238/276949 . Diese Antwort begrenzt die Länge UND verhindert, dass sich ein Puffer nach Erreichen des Grenzwerts kontinuierlich füllt, sodass Ihre Rücktaste ordnungsgemäß funktioniert.
Martin Konecny

Antworten:

1381

Dokumentation

Beispiel

android:maxLength="10"
Austin Hanson
quelle
26
D'oh! Mir geht es genauso. Ich habe mir den Code angesehen und es gibt keine setMaxLength-Methode.
Hpique
1
Was macht der Check hier? Es verlinkt nur auf diese Seite.
Was ist Schlaf
5
@ Vincent, du bist falsch. Das maxLengthAnwesen funktioniert noch.
Ashishduh
6
Beachten Sie, dass dies dem android:maxLengthentspricht. InputFilter.LengthFilterWenn Sie also den Filter programmgesteuert ändern, haben Sie auch den XML-Filter geändert.
mr5
20
Beachten Sie für die Personen, die sagen, dass dies nicht funktioniert, dass der Aufruf setFiltersnicht mehr android:maxLengthfunktioniert, da der vom XML-Code festgelegte Filter überschrieben wird. Mit anderen Worten, wenn Sie Filter programmgesteuert festlegen, müssen Sie sie alle programmgesteuert festlegen.
Ian Newson
339

Verwenden Sie einen Eingabefilter, um die maximale Länge einer Textansicht zu begrenzen.

TextView editEntryView = new TextView(...);
InputFilter[] filterArray = new InputFilter[1];
filterArray[0] = new InputFilter.LengthFilter(8);
editEntryView.setFilters(filterArray);
Jerry
quelle
5
Dies ist sehr nützlich, wenn jemand bereits welche gemacht hat InputFilter. Es wird android:maxlengthin der XML-Datei überschrieben , daher müssen wir LengthFilterdiesen Weg hinzufügen .
Seblis
Ich denke, Ihre Antwort ist die beste Antwort, da sie dynamischer ist, +1
Muhannad A.Alhariri
197
EditText editText = new EditText(this);
int maxLength = 3;    
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});
Emran Hamza
quelle
Dies ist ähnlich wie Android es mit der XML macht.
Nicolas Tyler
4
Wie kann ich die Mindestlänge einstellen?
Akhila Madari
@AkhilaMadari, wahrscheinlich mit TextWatcher.
CoolMind
65

Ein Hinweis für Personen, die bereits einen benutzerdefinierten Eingabefilter verwenden und auch die maximale Länge begrenzen möchten:

Wenn Sie Eingabefilter im Code zuweisen, werden alle zuvor eingestellten Eingabefilter gelöscht, einschließlich eines Satzes mit android:maxLength. Ich habe dies herausgefunden, als ich versucht habe, einen benutzerdefinierten Eingabefilter zu verwenden, um die Verwendung einiger Zeichen zu verhindern, die wir in einem Kennwortfeld nicht zulassen. Nach dem Setzen dieses Filters mit setFilters wurde die maxLength nicht mehr beobachtet. Die Lösung bestand darin, maxLength und meinen benutzerdefinierten Filter programmgesteuert zusammenzusetzen. Etwas wie das:

myEditText.setFilters(new InputFilter[] {
        new PasswordCharFilter(), new InputFilter.LengthFilter(20)
});
goto10
quelle
5
Sie können vorhandene Filter zuerst abrufen als: InputFilter [] existierende Filter = editText.getFilters ();
Fügen Sie
39
TextView tv = new TextView(this);
tv.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(250) });
ramo2712
quelle
7
Sicher, nur für Android
VAdaihiep
27

Ich hatte dieses Problem und ich denke, wir vermissen eine gut erklärte Methode, dies programmgesteuert zu tun, ohne die bereits eingestellten Filter zu verlieren.

Festlegen der Länge in XML:

Wie in der akzeptierten Antwort korrekt angegeben, definieren Sie in Ihrem EditText-XML Folgendes, wenn Sie eine feste Länge für einen EditText definieren möchten, die Sie in Zukunft nicht weiter ändern werden:

android:maxLength="10" 

Länge programmgesteuert einstellen

Um die Länge programmgesteuert einzustellen, müssen Sie sie über ein einstellen InputFilter. Wenn Sie jedoch einen neuen InputFilter erstellen und auf setzen, EditTextgehen alle anderen bereits definierten Filter (z. B. maxLines, inputType usw.) verloren, die Sie möglicherweise entweder über XML oder programmgesteuert hinzugefügt haben.

Das ist also FALSCH :

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

Um zu vermeiden, dass zuvor hinzugefügte Filter verloren gehen, müssen Sie diese Filter abrufen, den neuen hinzufügen (in diesem Fall maxLength) und die Filter EditTextwie folgt zurücksetzen :

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 hat es jedoch für alle einfacher gemacht. Sie müssen den Filter auch zu den bereits vorhandenen hinzufügen, aber Sie können dies mit einem einfachen:

editText.filters += InputFilter.LengthFilter(maxLength)
Ricardo
quelle
23

Für alle anderen, die sich fragen, wie sie dies erreichen können, ist hier meine erweiterte EditTextKlasse EditTextNumeric.

.setMaxLength(int) - Legt die maximale Anzahl von Ziffern fest

.setMaxValue(int) - Maximaler ganzzahliger Wert begrenzen

.setMin(int) - minimalen ganzzahligen Wert begrenzen

.getValue() - Ganzzahligen Wert abrufen

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

Anwendungsbeispiel:

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

Alle anderen Methoden und Attribute, die für gelten EditText, funktionieren natürlich auch.

Martynas Januškauskas
quelle
1
Es wäre besser, wenn wir dies in XML-Layout hinzufügen. Ich erhalte eine Fehlermeldung bei der Verwendung von XML. Verursacht durch: android.view.InflateException: Binäre XML-Dateizeile # 47: Fehler beim Aufblasen der Klasse com.passenger.ucabs.utils.EditTextNumeric
Shihab Uddin
@Martynas Haben Sie den gleichen Fehler wie Shihab_returns eine Lösung?
Pranaysharma
17

Aufgrund der Beobachtung von goto10 habe ich den folgenden Code zusammengestellt, um zu verhindern, dass andere Filter durch Einstellen der maximalen Länge verloren gehen:

/**
 * 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 });
    }
}
Tim Gallagher
quelle
3
Möglicherweise möchten Sie den Code leicht aktualisieren. Das zugewiesene Array muss curFilters.length + 1 groß sein. Nachdem Sie newFilters erstellt haben, haben Sie "this" nicht für das neu zugewiesene Array festgelegt. InputFilter newFilters [] = neuer 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()});
Kishore Reddy
quelle
12

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)
João Carlos
quelle
8

Eine andere Möglichkeit, dies zu erreichen, besteht darin, der XML-Datei die folgende Definition hinzuzufügen:

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

Dadurch wird die maximale Länge des EditTextWidgets auf 6 Zeichen begrenzt.

user2586194
quelle
6

Von material.io , können Sie TextInputEditTextmit kombiniert 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>

Sie können ein Passwort EditText mit drawable konfigurieren:

Passwort Beispiel

Oder Sie können die Textlänge mit / ohne Zähler begrenzen:

Gegenbeispiel

Abhängigkeit:

implementation 'com.google.android.material:material:1.1.0-alpha02'
RonTLV
quelle
6

XML

android:maxLength="10"

Programmatisch:

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

Hinweis: Intern analysieren EditText & TextView den Wert von android:maxLengthin XML und verwenden ihn InputFilter.LengthFilter()zum Anwenden .

Siehe: TextView.java # L1564

nhoxbypass
quelle
2

Dies ist eine benutzerdefinierte EditText-Klasse, mit der der Längenfilter zusammen mit anderen Filtern verwendet werden kann. Dank der Antwort von Tim Gallagher (unten)

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 });
        }
    }
}
Gal Rom
quelle
2

es einfache Weise in XML:

android:maxLength="4"

Wenn Sie 4 Zeichen in XML-Bearbeitungstext setzen müssen, verwenden Sie diese Option

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

Das funktioniert gut ...

android:maxLength="10"

Dies akzeptiert nur 10Zeichen.

Sanjay Kumaar
quelle
2

Versuchen Sie dies programmgesteuert für Java :

myEditText(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
reza_khalafi
quelle
1
Sie haben vergessen, die Methode aufzurufen, so dass es aussehen sollte:myEditText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
StevenTB
1

Ich hatte viele gute Lösungen gesehen, möchte aber eine meiner Meinung nach vollständigere und benutzerfreundlichere Lösung nennen, darunter:

1, Grenzlänge.
2, Wenn Sie mehr eingeben, geben Sie einen Rückruf, um Ihren Toast auszulösen.
3, Cursor kann in der Mitte oder am Ende sein.
4, Benutzer kann durch Einfügen einer Zeichenfolge eingeben.
5, Überlaufeingabe immer verwerfen und Ursprung behalten.

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

Was ich nicht getan habe, ist, wenn der Benutzer einen Teil der aktuellen Eingabe hervorhebt und versucht, eine sehr lange Zeichenfolge einzufügen, weiß ich nicht, wie die Hervorhebung wiederhergestellt werden soll.

Beispielsweise wird die maximale Länge auf 10 festgelegt, der Benutzer gibt '12345678' ein und markiert '345' als Hervorhebung. Versuchen Sie, eine Zeichenfolge von '0000' einzufügen, die die Begrenzung überschreitet.

Wenn ich versuche, edit_text.setSelection (start = 2, end = 4) zu verwenden, um den Ursprungsstatus wiederherzustellen, wird nur 2 Leerzeichen als '12 345 678 'eingefügt, nicht das Ursprungshighlight. Ich möchte, dass jemand das löst.

hyyou2010
quelle
1

Sie können android:maxLength="10"im EditText verwenden. (Hier beträgt das Limit bis zu 10 Zeichen.)

Jocelin
quelle
0

Kotlin:

edit_text.filters += InputFilter.LengthFilter(10)

ZTE Blade A520hat seltsame Wirkung. Wenn Sie mehr als 10 Symbole eingeben (z. B. 15), EditTextwerden die ersten 10 angezeigt, andere 5 sind jedoch nicht sichtbar und nicht zugänglich. Wenn Sie jedoch Symbole mit löschen Backspace, werden zuerst die rechten 5 Symbole gelöscht und dann die verbleibenden 10 entfernt. Um dieses Verhalten zu überwinden, verwenden Sie eine Lösung :

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

oder dieses:

android:inputType="textNoSuggestions"

oder dies, wenn Sie Vorschläge haben möchten:

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)
CoolMind
quelle
0

es einfache Weise in XML:

android:maxLength="@{length}"

Zum programmgesteuerten Einstellen können Sie die folgende Funktion verwenden

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()]));
    }
}
Mohamed Fadel Buffon
quelle