Apa cara terbaik untuk membatasi panjang teks EditText di Android

702

Apa cara terbaik untuk membatasi panjang teks EditTextdi Android?

Apakah ada cara untuk melakukan ini melalui xml?

hpique
sumber
1
Saya ingin mengatur jumlah karakter maksimum untuk EditText saya. Pada awalnya tidak jelas bahwa batas panjang teks adalah hal yang sama. (Hanya catatan untuk traveler yang bingung).
Katedral Pillon
The jawaban yang benar di sini : stackoverflow.com/a/19222238/276949 . Jawaban ini membatasi panjang DAN mencegah buffer terus mengisi setelah mencapai batas, oleh karena itu memungkinkan kunci backspace Anda berfungsi dengan baik.
Martin Konecny

Jawaban:

1381

Dokumentasi

Contoh

android:maxLength="10"
Austin Hanson
sumber
26
Doh! Hal yang sama terjadi pada saya. Saya sedang melihat kode, dan tidak ada metode setMaxLength.
hpique
1
apa yang dilakukan Cek di sini? Itu hanya tautan ke halaman ini.
Apa itu tidur
5
@Vincy, Anda salah. The maxLengthproperti masih bekerja.
ashishduh
6
Sadarilah bahwa android:maxLengthitu setara dengan InputFilter.LengthFilter, jadi ketika secara terprogram mengubah filternya, Anda juga telah memodifikasi filter XML-nya.
mr5
20
Untuk orang-orang yang mengatakan itu tidak berfungsi, ketahuilah bahwa panggilan setFiltersakan berhenti android:maxLengthberfungsi, karena menimpa filter yang ditetapkan oleh XML. Dengan kata lain, jika Anda mengatur filter apa pun secara terprogram, Anda harus mengatur semuanya secara terprogram.
Ian Newson
339

gunakan filter input untuk membatasi panjang maksimal tampilan teks.

TextView editEntryView = new TextView(...);
InputFilter[] filterArray = new InputFilter[1];
filterArray[0] = new InputFilter.LengthFilter(8);
editEntryView.setFilters(filterArray);
jerry
sumber
5
Ini sangat berguna jika seseorang sudah membuatnya InputFilter. Itu menimpa android:maxlengthdalam file xml, jadi kita perlu menambahkan LengthFiltercara ini.
Seblis
Saya pikir jawaban Anda adalah jawaban terbaik, karena lebih dinamis, +1
Muhannad A.Alhariri
197
EditText editText = new EditText(this);
int maxLength = 3;    
editText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength)});
Emran Hamza
sumber
Ini mirip dengan cara android melakukannya dengan xml.
Nicolas Tyler
4
Bagaimana cara menetapkan panjang minimum?
Akhila Madari
@AkhilaMadari, mungkin dengan TextWatcher.
CoolMind
65

Catatan untuk orang-orang yang sudah menggunakan filter input khusus dan juga ingin membatasi panjang maks:

Saat Anda menetapkan filter input dalam kode, semua filter input yang ditetapkan sebelumnya dihapus, termasuk satu filter dengan android:maxLength. Saya menemukan ini ketika mencoba menggunakan filter input khusus untuk mencegah penggunaan beberapa karakter yang tidak kami izinkan dalam bidang kata sandi. Setelah mengatur filter dengan setFilters, maxLength tidak lagi diamati. Solusinya adalah mengatur maxLength dan filter kustom saya secara terprogram. Sesuatu seperti ini:

myEditText.setFilters(new InputFilter[] {
        new PasswordCharFilter(), new InputFilter.LengthFilter(20)
});
kebagian10
sumber
5
Anda dapat mengambil filter yang ada terlebih dahulu sebagai, InputFilter [] existingFilters = editText.getFilters (); Kemudian tambahkan filter Anda bersama dengan filter yang ada ini
subair_a
39
TextView tv = new TextView(this);
tv.setFilters(new InputFilter[]{ new InputFilter.LengthFilter(250) });
ramo2712
sumber
7
Tentu, hanya untuk android
VAdaihiep
27

Saya telah mengalami masalah ini dan saya menganggap kita kehilangan cara yang dijelaskan dengan baik untuk melakukan ini secara terprogram tanpa kehilangan filter yang telah ditetapkan.

Mengatur panjang dalam XML:

Seperti yang dinyatakan oleh jawaban yang diterima dengan benar, jika Anda ingin menentukan panjang yang tetap ke EditText yang tidak akan Anda ubah lebih lanjut di masa mendatang, cukup tentukan di EditText XML Anda:

android:maxLength="10" 

Mengatur panjang secara terprogram

Untuk mengatur panjang secara pemrograman Anda harus mengaturnya melalui InputFilter. Tetapi jika Anda membuat InputFilter baru dan mengaturnya keEditText Anda akan kehilangan semua filter lain yang sudah didefinisikan (misalnya maxLines, inputType, dll) yang mungkin Anda tambahkan baik melalui XML atau secara terprogram.

Jadi ini SALAH :

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

Untuk menghindari kehilangan filter yang ditambahkan sebelumnya, Anda perlu mendapatkan filter tersebut, tambahkan yang baru (maxLength dalam hal ini), dan atur kembali filter ke EditText sebagai berikut:

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

Namun Kotlin membuatnya lebih mudah untuk semua orang, Anda juga perlu menambahkan filter ke yang sudah ada tetapi Anda dapat mencapainya dengan sederhana:

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

Untuk orang lain yang bertanya-tanya bagaimana mencapai ini, inilah EditTextkelas saya yang diperluas EditTextNumeric.

.setMaxLength(int) - mengatur jumlah digit maksimum

.setMaxValue(int) - membatasi nilai integer maksimum

.setMin(int) - membatasi nilai integer minimum

.getValue() - dapatkan nilai integer

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

Contoh penggunaan:

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

Semua metode dan atribut lain yang berlaku EditText, tentu saja berfungsi juga.

Martynas Januškauskas
sumber
1
Akan lebih baik jika kita menambahkan ini di Layout xml. Saya mendapatkan kesalahan dengan ini ketika menggunakan xml Disebabkan oleh: android.view.InflateException: Binary XML file baris # 47: Kesalahan membesarkan kelas com.passenger.ucabs.utils.EditTextNumeric
Shihab Uddin
@Martynas Mendapat kesalahan yang sama seperti Shihab_returns solusi apa pun?
Pranaysharma
17

Karena pengamatan goto10, saya mengumpulkan kode berikut untuk melindungi dari kehilangan filter lain dengan mengatur panjang maks:

/**
 * 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
sumber
3
Anda mungkin ingin memperbarui sedikit kodenya. Array yang dialokasikan harus berukuran curFilters.length + 1 dan setelah Anda membuat newFilters, Anda tidak menyetel "ini" ke array yang baru dialokasikan. InputFilter newFilters [] = InputFilter baru [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
sumber
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)
João Carlos
sumber
8

Cara lain untuk mencapai ini adalah dengan menambahkan definisi berikut ke 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"/>

Ini akan membatasi panjang maksimal EditTextwidget hingga 6 karakter.

pengguna2586194
sumber
6

Dari material.io , Anda dapat menggunakan TextInputEditTextdikombinasikan dengan 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>

Anda dapat mengonfigurasi EditText kata sandi dengan drawable:

contoh kata sandi

Atau Anda dapat membatasi panjang teks dengan / tanpa penghitung:

contoh konter

Ketergantungan:

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

XML

android:maxLength="10"

Secara terprogram:

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

Catatan: secara internal, EditText & TextView mem-parsing nilai android:maxLengthdalam XML dan gunakan InputFilter.LengthFilter()untuk menerapkannya.

Lihat: TextView.java # L1564

nhoxbypass
sumber
2

Ini adalah kelas EditText kustom yang memungkinkan filter Panjang untuk hidup bersama dengan filter lainnya. Terima kasih atas Jawaban Tim Gallagher (di bawah)

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
sumber
2

cara sederhana di xml:

android:maxLength="4"

jika Anda perlu mengatur 4 karakter dalam xml edit-text, gunakan ini

<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
sumber
2

Ini berfungsi dengan baik ...

android:maxLength="10"

ini hanya akan menerima 10karakter.

Sanjay Kumaar
sumber
2

Coba ini untuk Java secara terprogram :

myEditText(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
reza_khalafi
sumber
1
Anda lupa memanggil metode sehingga akan terlihat seperti:myEditText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
StevenTB
1

Saya telah melihat banyak solusi bagus, tetapi saya ingin memberikan apa yang saya pikir sebagai solusi yang lebih lengkap dan ramah pengguna, yang meliputi:

1, Batas panjang.
2, Jika masukan lebih banyak, berikan panggilan balik untuk memicu roti panggang Anda.
3, Kursor bisa di tengah atau ekor.
4, Pengguna dapat memasukkan dengan menempelkan string.
5, Selalu buang input overflow dan pertahankan asal.

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

Apa yang saya gagal lakukan adalah, jika pengguna menyorot bagian dari input saat ini dan mencoba menempelkan string yang sangat panjang, saya tidak tahu cara mengembalikan sorot.

Seperti, panjang maks diatur ke 10, pengguna memasukkan '12345678', dan tandai '345' sebagai highlight, dan mencoba menempelkan string '0000' yang akan melebihi batasan.

Ketika saya mencoba menggunakan edit_text.setSelection (start = 2, end = 4) untuk mengembalikan status asal, hasilnya adalah, ia hanya menyisipkan 2 spasi sebagai '12 345 678 ', bukan highlight asal. Saya ingin seseorang menyelesaikannya.

hyyou2010
sumber
1

Anda dapat menggunakan android:maxLength="10"dalam EditText. (Di sini batasnya hingga 10 karakter)

Jocelin
sumber
0

Kotlin:

edit_text.filters += InputFilter.LengthFilter(10)

ZTE Blade A520memiliki efek aneh. Ketika Anda mengetik lebih dari 10 simbol (misalnya, 15), EditTextmenunjukkan 10 pertama, tetapi 5 lainnya tidak terlihat dan tidak dapat diakses. Tetapi ketika Anda menghapus simbol dengan Backspace, itu pertama menghapus kanan 5 simbol dan kemudian menghapus sisa 10. Untuk mengatasi perilaku ini gunakan solusi :

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

atau ini:

android:inputType="textNoSuggestions"

atau ini, jika Anda ingin memiliki saran:

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
sumber
0

cara sederhana di xml:

android:maxLength="@{length}"

untuk mengaturnya secara terprogram Anda dapat menggunakan fungsi berikut

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
sumber