Cách tốt nhất để giới hạn độ dài văn bản của EditText trong Android


702

Cách tốt nhất để giới hạn độ dài văn bản của EditTextAndroid là gì?

Có cách nào để làm điều này qua xml không?


1
Tôi muốn đặt số lượng ký tự tối đa cho EditText của mình. Lúc đầu, không rõ ràng rằng giới hạn độ dài văn bản là điều tương tự. (Chỉ là một lưu ý cho một du khách nhầm lẫn khác).
Katedral Pillon

Các câu trả lời đúng là ở đây : stackoverflow.com/a/19222238/276949 . Câu trả lời này giới hạn độ dài VÀ ngăn bộ đệm liên tục lấp đầy sau khi đạt giới hạn, do đó cho phép phím backspace của bạn hoạt động chính xác.
Martin Konecny

Câu trả lời:


1381

Tài liệu

Thí dụ

android:maxLength="10"

26
Ôi! Điều tương tự cũng xảy ra với tôi. Tôi đã xem mã và không có phương thức setMaxLpm.
hpique

1
Kiểm tra ở đây làm gì? Nó chỉ liên kết đến trang này.
giấc ngủ

5
@Vincy, bạn không chính xác. Tài maxLengthsản vẫn hoạt động.
ashishduh

6
Xin lưu ý rằng android:maxLengthnó tương đương với InputFilter.LengthFilter, vì vậy, khi lập trình thay đổi bộ lọc, bạn cũng đã sửa đổi bộ lọc XML của nó.
mr5

20
Đối với những người nói rằng nó không hoạt động, hãy lưu ý rằng việc gọi setFilterssẽ ngừng hoạt android:maxLengthđộng, bởi vì nó ghi đè lên bộ lọc do XML đặt. Nói cách khác, nếu bạn đặt bất kỳ bộ lọc nào theo chương trình, bạn phải đặt tất cả các bộ lọc theo chương trình.
Ian Newson

339

sử dụng bộ lọc đầu vào để giới hạn độ dài tối đa của chế độ xem văn bản.

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

5
Điều này rất hữu ích nếu ai đó đã thực hiện một số InputFilter. Nó ghi đè lên android:maxlengthtệp xml, vì vậy chúng ta cần thêm LengthFiltercách này.
Seblis

Tôi nghĩ rằng câu trả lời của bạn là câu trả lời hay nhất, vì nó năng động hơn, +1
Muhannad A.Alhariri

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

Điều này tương tự như cách Android làm với xml.
Nicolas Tyler

4
Làm thế nào tôi có thể thiết lập chiều dài tối thiểu?
Akhila Madari

@AkhilaMadari, có lẽ với TextWatcher.
CoolMind

65

Một lưu ý cho những người đã sử dụng bộ lọc đầu vào tùy chỉnh và cũng muốn giới hạn độ dài tối đa:

Khi bạn chỉ định các bộ lọc đầu vào trong mã, tất cả các bộ lọc đầu vào được đặt trước đó sẽ bị xóa, bao gồm một bộ với android:maxLength. Tôi đã phát hiện ra điều này khi cố gắng sử dụng bộ lọc đầu vào tùy chỉnh để ngăn việc sử dụng một số ký tự mà chúng tôi không cho phép trong trường mật khẩu. Sau khi thiết lập bộ lọc đó với setFilters, maxLpm không còn được quan sát. Giải pháp là đặt maxLimum và bộ lọc tùy chỉnh của tôi theo chương trình. Một cái gì đó như thế này:

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

5
Trước tiên, bạn có thể truy xuất các bộ lọc hiện tại dưới dạng InputFilter [] currentFilters = editText.getFilters (); Sau đó, thêm bộ lọc của bạn cùng với các bộ lọc hiện có này
subair_a

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

7
Chắc chắn, chỉ dành cho Android
VAdaihiep

27

Tôi đã gặp vấn đề này và tôi cho rằng chúng ta đang thiếu một cách giải thích rõ ràng để thực hiện việc này theo chương trình mà không làm mất các bộ lọc đã được đặt.

Đặt độ dài trong XML:

Vì câu trả lời được chấp nhận nêu chính xác, nếu bạn muốn xác định độ dài cố định cho EditText mà bạn sẽ không thay đổi thêm trong tương lai, chỉ cần xác định trong XML Chỉnh sửa của bạn:

android:maxLength="10" 

Đặt độ dài theo chương trình

Để đặt độ dài theo chương trình, bạn cần đặt chiều dài qua InputFilter. Nhưng nếu bạn tạo InputFilter mới và đặt nó vào thì EditTextbạn sẽ mất tất cả các bộ lọc đã được xác định khác (ví dụ: maxLines, inputType, v.v.) mà bạn có thể đã thêm thông qua XML hoặc theo chương trình.

Vì vậy, đây là SAI :

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

Để tránh mất các bộ lọc đã thêm trước đó, bạn cần lấy các bộ lọc đó, thêm bộ lọc mới (maxLpm trong trường hợp này) và đặt bộ lọc trở lại EditTextnhư sau:

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

Tuy nhiên, Kotlin giúp mọi người dễ dàng hơn, bạn cũng cần thêm bộ lọc vào những bộ lọc đã có nhưng bạn có thể đạt được điều đó một cách đơn giản:

editText.filters += InputFilter.LengthFilter(maxLength)

23

Đối với bất cứ ai khác tự hỏi làm thế nào để đạt được điều này, đây là EditTextlớp mở rộng của tôi EditTextNumeric.

.setMaxLength(int) - đặt số chữ số tối đa

.setMaxValue(int) - giới hạn giá trị nguyên tối đa

.setMin(int) - giới hạn giá trị nguyên tối thiểu

.getValue() - lấy giá trị nguyên

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

Ví dụ sử dụng:

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

Tất cả các phương pháp và thuộc tính khác áp dụng cho EditText, tất nhiên cũng hoạt động.


1
Sẽ tốt hơn nếu chúng ta thêm cái này trong Bố cục xml. Tôi gặp lỗi với điều này khi sử dụng xml Nguyên nhân bởi: android.view.InflateException: Dòng tệp nhị phân XML # 47: Lỗi thổi phồng lớp com.pasbah.ucabs.utils.EditTextNumeric
Shihab Uddin

@Martynas Có cùng một lỗi như Shihab_returns giải pháp nào không?
Pranaysharma

17

Do sự quan sát của goto10, tôi kết hợp các mã sau để bảo vệ khỏi mất các bộ lọc khác với cài đặt độ dài tối đa:

/**
 * 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
Bạn có thể muốn cập nhật mã một chút. Mảng được phân bổ cần có kích thước curFilters.length + 1 và sau khi bạn tạo newFilters, bạn đã không đặt "cái này" thành mảng mới được phân bổ. Bộ lọc đầu vào 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"

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)

8

Một cách khác bạn có thể đạt được điều này là bằng cách thêm định nghĩa sau vào tệp 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"/>

Điều này sẽ giới hạn độ dài tối đa của EditTextwidget chỉ còn 6 ký tự.


6

Từ Material.io , bạn có thể sử dụng TextInputEditTextkết hợp với 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>

Bạn có thể định cấu hình mật khẩu EditText với drawable:

ví dụ mật khẩu

Hoặc bạn có thể giới hạn độ dài văn bản có / không có bộ đếm:

ví dụ truy cập

Phụ thuộc:

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

6

XML

android:maxLength="10"

Lập trình:

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

Lưu ý: trong nội bộ, EditText & TextView phân tích giá trị của android:maxLengthXML và sử dụng InputFilter.LengthFilter()để áp dụng nó.

Xem: TextView.java # L1564


2

Đây là Lớp EditText tùy chỉnh cho phép bộ lọc Độ dài hoạt động cùng với các bộ lọc khác. Cảm ơn Câu trả lời của Tim Gallagher (bên dưới)

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

cách đơn giản trong xml:

android:maxLength="4"

Nếu bạn yêu cầu đặt 4 ký tự trong văn bản chỉnh sửa xml, hãy sử dụng

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

2

Điều này hoạt động tốt ...

android:maxLength="10"

Điều này sẽ chỉ chấp nhận các 10nhân vật.


2

Hãy thử điều này cho Java theo lập trình :

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

1
Bạn đã quên gọi phương thức để nó trông giống như:myEditText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
StevenTB

1

Tôi đã thấy rất nhiều giải pháp tốt, nhưng tôi muốn đưa ra một giải pháp mà tôi nghĩ là hoàn hảo hơn và thân thiện với người dùng hơn, bao gồm:

1, Giới hạn chiều dài.
2, Nếu nhập thêm, hãy gọi lại để kích hoạt bánh mì nướng của bạn.
3, Con trỏ có thể ở giữa hoặc đuôi.
4, Người dùng có thể nhập bằng cách dán một chuỗi.
5, Luôn loại bỏ đầu vào tràn và giữ nguồn gốc.

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

Điều tôi thất bại là, nếu người dùng đánh dấu một phần của đầu vào hiện tại và cố gắng dán một chuỗi rất dài, tôi không biết cách khôi phục lại phần tô sáng.

Chẳng hạn như, độ dài tối đa được đặt thành 10, người dùng đã nhập '12345678' và đánh dấu '345' làm điểm sáng và thử dán chuỗi '0000' sẽ vượt quá giới hạn.

Khi tôi cố gắng sử dụng edit lòng.setSelection (start = 2, end = 4) để khôi phục trạng thái gốc, kết quả là, nó chỉ chèn 2 khoảng trắng là '12 345 678 ', không phải là điểm nổi bật gốc. Tôi muốn ai đó giải quyết điều đó.


1

Bạn có thể sử dụng android:maxLength="10"trong EditText. (Ở đây giới hạn tối đa là 10 ký tự)


0

Kotlin:

edit_text.filters += InputFilter.LengthFilter(10)

ZTE Blade A520có tác dụng lạ. Khi bạn nhập hơn 10 ký hiệu (ví dụ: 15), EditTexthiển thị 10 ký tự đầu tiên, nhưng 5 ký hiệu khác không hiển thị và không thể truy cập. Nhưng khi bạn xóa các ký hiệu Backspace, trước tiên, nó sẽ xóa đúng 5 ký hiệu và sau đó xóa các ký hiệu còn lại 10. Để khắc phục hành vi này, hãy sử dụng giải pháp :

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

hoặc này:

android:inputType="textNoSuggestions"

hoặc điều này, nếu bạn muốn có đề xuất:

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

cách đơn giản trong xml:

android:maxLength="@{length}"

để cài đặt nó theo chương trình, bạn có thể sử dụng chức năng sau

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()]));
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.