Jaki jest najlepszy sposób ograniczenia długości tekstu EditText w Androidzie


700

Jaki jest najlepszy sposób ograniczenia długości tekstu EditTextw Androidzie?

Czy jest na to sposób za pomocą xml?


1
Chciałem ustawić maksymalną liczbę znaków dla mojego EditText. Na początku nie było oczywiste, że limit długości tekstu był taki sam. (Tylko uwaga dla innego zdezorientowanego podróżnika).
Katedral Pillon

Poprawna odpowiedź jest tutaj : stackoverflow.com/a/19222238/276949 . Ta odpowiedź ogranicza długość ORAZ zapobiega ciągłemu zapełnianiu się bufora po osiągnięciu limitu, dzięki czemu klawisz Backspace działa poprawnie.
Martin Konecny,

Odpowiedzi:


1378

Dokumentacja

Przykład

android:maxLength="10"

26
Nie! To samo przytrafiło mi się. Patrzyłem na kod i nie ma metody setMaxLength.
hpique

1
co robi tutaj Check? To tylko linki do tej strony.
czym jest sen

5
@Vincy, jesteś w błędzie. maxLengthNieruchomość nadal działa.
ashishduh

6
Pamiętaj, że android:maxLengthjest to równoważne z tym InputFilter.LengthFilter, więc programowo zmieniając filtr, zmodyfikowałeś również jego filtr XML.
mr5

20
Ludziom, którzy twierdzą, że to nie działa, pamiętaj, że wywołanie setFiltersprzestanie android:maxLengthdziałać, ponieważ zastąpi zestaw filtrów ustawiony przez XML. Innymi słowy, jeśli ustawisz dowolne filtry programowo, musisz ustawić je wszystkie programowo.
Ian Newson

339

użyj filtra wejściowego, aby ograniczyć maksymalną długość widoku tekstu.

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

5
Jest to bardzo przydatne, jeśli ktoś już coś zrobił InputFilter. Zastępuje android:maxlengthw pliku xml, więc musimy dodać w LengthFilterten sposób.
Seblis,

Myślę, że twoja odpowiedź jest najlepsza, ponieważ jest bardziej dynamiczna, +1
Muhannad A.Alhariri

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

Jest to podobne do sposobu, w jaki android robi to za pomocą xml.
Nicolas Tyler,

4
Jak ustawić minimalną długość?
Akhila Madari

@AkhilaMadari, prawdopodobnie z TextWatcher.
CoolMind,

65

Uwaga dla osób, które już korzystają z niestandardowego filtra wejściowego i chcą również ograniczyć maksymalną długość:

Po przypisaniu filtrów wejściowych w kodzie wszystkie wcześniej ustawione filtry wejściowe są kasowane, w tym jeden zestaw z android:maxLength. Przekonałem się o tym, próbując użyć niestandardowego filtra wejściowego, aby zapobiec użyciu niektórych znaków, które nie są dozwolone w polu hasła. Po ustawieniu tego filtra za pomocą setFilters nie obserwowano już maxLength. Rozwiązaniem było programowe ustawienie maxLength i mojego niestandardowego filtra. Coś takiego:

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

5
Możesz najpierw pobrać istniejące filtry, ponieważ InputFilter [] existFilters = editText.getFilters (); Następnie dodaj swój filtr wraz z istniejącymi filtrami
subair_a

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

7
Jasne, tylko dla Androida
VAdaihiep

27

Miałem ten problem i uważam, że brakuje nam dobrze wyjaśnionego sposobu robienia tego programowo bez utraty ustawionych filtrów.

Ustawianie długości w XML:

Zgodnie z prawidłową odpowiedzią, jeśli chcesz zdefiniować stałą długość w EditText, którego nie będziesz dalej zmieniać w przyszłości, po prostu zdefiniuj w EditText XML:

android:maxLength="10" 

Programowe ustawianie długości

Aby programowo ustawić długość, musisz ustawić ją za pomocą InputFilter. Ale jeśli utworzysz nowy InputFilter i ustawisz go EditText, stracisz wszystkie inne już zdefiniowane filtry (np. MaxLines, inputType itp.), Które mogłeś dodać albo przez XML, albo programowo.

To jest NIEPRAWIDŁOWE :

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

Aby uniknąć utraty wcześniej dodanych filtrów, musisz uzyskać te filtry, dodać nowy (w tym przypadku maxLength) i ustawić filtry z powrotem na EditTextnastępujące:

Jawa

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 jednak ułatwił wszystkim, musisz również dodać filtr do już istniejących, ale możesz to zrobić za pomocą prostego:

editText.filters += InputFilter.LengthFilter(maxLength)

23

Dla każdego, kto zastanawia się, jak to osiągnąć, oto moja rozszerzona EditTextklasa EditTextNumeric.

.setMaxLength(int) - ustawia maksymalną liczbę cyfr

.setMaxValue(int) - ograniczenie maksymalnej wartości całkowitej

.setMin(int) - ograniczenie minimalnej wartości całkowitej

.getValue() - uzyskać wartość całkowitą

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

Przykładowe użycie:

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

EditTextOczywiście wszystkie inne metody i atrybuty, które mają zastosowanie , również działają.


1
Byłoby lepiej, gdybyśmy dodali to w układzie xml. Dostaję błąd podczas używania xml Przyczyna: android.view.InflateException: Binarny plik XML linii # 47: Błąd podczas pompowania klasy com.passenger.ucabs.utils.EditTextNumeric
Shihab Uddin

@Martynas Masz taki sam błąd jak Shihab_returns jakieś rozwiązanie?
Pranaysharma

17

Ze względu na obserwację goto10, zestawiłem następujący kod, aby zabezpieczyć się przed utratą innych filtrów z ustawieniem maksymalnej długości:

/**
 * 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
Możesz nieco zaktualizować kod. Przydzielona tablica musi mieć rozmiar curFilters.length + 1, a po utworzeniu nowych filtrów nie ustawiono „to” na nowo przydzieloną tablicę. InputFilter newFilters [] = nowy 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"

Jawa:

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

Innym sposobem na osiągnięcie tego jest dodanie do pliku XML następującej definicji:

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

Ograniczy to maksymalną długość EditTextwidgetu do 6 znaków.


6

Z material.io możesz używać w TextInputEditTextpołączeniu z 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>

Możesz skonfigurować hasło EditText z możliwością rysowania:

przykład hasła

Lub możesz ograniczyć długość tekstu za pomocą / bez licznika:

licznik przykład

Zależność:

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

6

XML

android:maxLength="10"

Programowo:

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

Uwaga: wewnętrznie EditText i TextView analizują wartość android:maxLengthw XML i używają InputFilter.LengthFilter()do jej zastosowania.

Zobacz: TextView.java # L1564


2

Jest to niestandardowa klasa EditText, która pozwala na stosowanie filtra Length wraz z innymi filtrami. Dzięki odpowiedzi Tima Gallaghera (poniżej)

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

prosty sposób w XML:

android:maxLength="4"

jeśli musisz ustawić 4 znaki w edytorze tekstu XML, użyj tego

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


2

Wypróbuj programowo dla Java :

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

1
Zapomniałeś wywołać metodę, więc powinna wyglądać następująco:myEditText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
StevenTB

1

Widziałem wiele dobrych rozwiązań, ale chciałbym podać coś, co uważam za bardziej kompletne i przyjazne dla użytkownika rozwiązanie, które obejmuje:

1, Limit długości.
2, Jeśli wprowadzisz więcej, oddzwoń, aby uruchomić toast.
3, Kursor może znajdować się na środku lub ogonie.
4, użytkownik może wprowadzić, wklejając ciąg.
5, Zawsze odrzucaj dane przelewu i zachowaj pochodzenie.

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

Nie udało mi się, jeśli użytkownik podświetli część bieżącego wejścia i spróbuje wkleić bardzo długi ciąg, nie wiem, jak przywrócić podświetlenie.

Na przykład maksymalna długość jest ustawiona na 10, użytkownik wprowadził „12345678” i oznaczył „345” jako podświetlony, i próbował wkleić ciąg „0000”, który przekroczy ograniczenia.

Kiedy próbuję użyć edit_text.setSelection (start = 2, end = 4) w celu przywrócenia stanu początkowego, wynik jest taki, że po prostu wstawiam 2 spacje jako „12 345 678”, a nie podświetlenie źródła. Chciałbym, żeby ktoś to rozwiązał.


1

Możesz użyć android:maxLength="10"w EditText. (Tutaj limit wynosi do 10 znaków)


0

Kotlin:

edit_text.filters += InputFilter.LengthFilter(10)

ZTE Blade A520ma dziwny efekt. Gdy wpiszesz więcej niż 10 symboli (na przykład 15), EditTextpokazuje pierwsze 10, ale pozostałe 5 nie są widoczne i niedostępne. Ale kiedy usuwasz symbole za pomocą Backspace, najpierw usuwa właściwe 5 symboli, a następnie usuwa pozostałe 10. Aby obejść to zachowanie, użyj rozwiązania :

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

albo to:

android:inputType="textNoSuggestions"

lub to, jeśli chcesz mieć sugestie:

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

prosty sposób w XML:

android:maxLength="@{length}"

do programowego ustawienia możesz użyć następującej funkcji

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()]));
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.