Android'de EditText'in metin uzunluğunu sınırlamanın en iyi yolu nedir?


703

EditTextAndroid cihazlarda metin uzunluğunu sınırlamanın en iyi yolu nedir ?

Bunu xml ile yapmanın bir yolu var mı?


1
EditText'im için maksimum karakter sayısını ayarlamak istedim. İlk başta metin uzunluğu sınırının aynı şey olduğu açık değildi. (Sadece başka bir karıştırmayın gezgin için bir not).
Katedral Pillon

Doğru cevabı burada : stackoverflow.com/a/19222238/276949 . Bu cevap uzunluğu sınırlar VE bir tamponun sınıra ulaştıktan sonra sürekli dolmasını önler, böylece geri tuşu anahtarınızın düzgün çalışmasına izin verir .
Martin Konecny

Yanıtlar:


1382

belgeleme

Misal

android:maxLength="10"

26
D'oh! Aynı şey bana da oldu. Ben koda bakıyordum ve bir setMaxLength yöntemi yok.
hpique

1
Buradaki Check ne yapıyor? Sadece bu sayfaya bağlantı veriyor.
uyku nedir

5
@Vincy, yanılıyorsun. maxLengthMülkiyet hala çalışıyor.
ashishduh

6
Bunun android:maxLengtheşdeğer olduğunu unutmayın InputFilter.LengthFilter, bu nedenle filtresini program aracılığıyla değiştirirken, XML filtresini de değiştirdiniz.
mr5

20
İşe yaramadığını söyleyenlere , XML tarafından ayarlanan filtrenin üzerine yazdığı için çağrının çalışmayı setFiltersdurduracağını unutmayın android:maxLength. Başka bir deyişle, herhangi bir filtreyi programlı olarak ayarlarsanız, bunların tümünü programlı olarak ayarlamanız gerekir.
Ian Newson

339

metin görünümünün maksimum uzunluğunu sınırlamak için bir giriş filtresi kullanın.

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

6
Birisi zaten biraz yapmışsa bu çok yararlıdır InputFilter. android:maxlengthXml dosyasında geçersiz kılar , bu yüzden LengthFilterbu şekilde eklememiz gerekir .
Seblis

Sanırım cevabınız en iyi cevaptır, çünkü daha dinamiktir, +1
Muhannad A.Alhariri

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

Bu android xml ile yaptığı gibi.
Nicolas Tyler

4
Minimum uzunluğu nasıl ayarlayabilirim?
Akhila Madari

@AkhilaMadari, muhtemelen ile TextWatcher.
CoolMind

65

Zaten özel bir giriş filtresi kullanan ve ayrıca maksimum uzunluğu sınırlamak isteyen kişilere not :

Kodda giriş filtreleri atadığınızda, bir küme de dahil olmak üzere önceden ayarlanmış tüm giriş filtreleri temizlenir android:maxLength. Bir şifre alanında izin vermediğimiz bazı karakterlerin kullanılmasını önlemek için özel bir giriş filtresi kullanmaya çalışırken bunu öğrendim. Bu filtreyi setFilters ile ayarladıktan sonra, maxLength artık gözlenmedi. Çözüm, maxLength ve özel filtremi programlı olarak ayarlamaktı. Bunun gibi bir şey:

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

5
Öncelikle mevcut filtreleri alabilirsiniz; InputFilter [] existingFilters = editText.getFilters (); Ardından, bu mevcut filtrelerle birlikte filtrenizi ekleyin
subair_a

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

7
Tabii, sadece android için
VAdaihiep

27

Bu sorunu yaşadım ve zaten ayarlanmış filtreleri kaybetmeden bunu programlı olarak yapmanın iyi açıklanmış bir yolunu kaçırdığımızı düşünüyorum.

XML'de uzunluğu ayarlama:

Kabul edilen yanıtın doğru şekilde ifade ettiği gibi, ileride daha fazla değiştirmeyeceğiniz bir EditText için sabit bir uzunluk tanımlamak istiyorsanız, EditText XML'nizde tanımlamanız yeterlidir:

android:maxLength="10" 

Uzunluğu programlı olarak ayarlama

Uzunluğu programlı olarak ayarlamak için bir InputFilter. Ancak, yeni bir InputFilter oluşturup bu EditTextfiltreyi ayarlarsanız, XML aracılığıyla veya program aracılığıyla eklemiş olabileceğiniz diğer tüm tanımlanmış filtreleri (örn. MaxLines, inputType, vb.) Kaybedersiniz.

Yani bu YANLIŞ :

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

Önceden eklenen filtreleri kaybetmemek için bu filtreleri almanız, yenisini (bu durumda maxLength) eklemeniz ve filtreleri EditTextaşağıdaki gibi tekrar ayarlamanız gerekir :

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 , herkes için kolaylaştırdı, aynı zamanda mevcut olanlara da filtre eklemeniz gerekiyor, ancak bunu basit bir şekilde elde edebilirsiniz:

editText.filters += InputFilter.LengthFilter(maxLength)

23

Bunu nasıl başaracağını merak eden herkes için, işte benim genişletilmiş EditTextsınıfım EditTextNumeric.

.setMaxLength(int) - maksimum basamak sayısını ayarlar

.setMaxValue(int) - maksimum tamsayı değerini sınırla

.setMin(int) - minimum tam sayı değerini sınırla

.getValue() - tamsayı değeri al

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

Örnek kullanım:

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

EditTextElbette geçerli olan diğer tüm yöntemler ve nitelikler de işe yarar.


1
Bunu xml Layout'a eklersek daha iyi olur. Ben xml kullanırken bununla hata alıyorum Neden: android.view.InflateException: İkili XML dosya satırı # 47: Sınıf com.passenger.ucabs.utils.ElektTextNumeric
Shihab Uddin

@ Shartynas Shihab_returns herhangi bir çözüm gibi aynı hatayı mı aldınız?
Pranaysharma

17

Goto10'un gözlemi nedeniyle, maksimum uzunluğu ayarlayarak diğer filtreleri kaybetmeye karşı korumak için aşağıdaki kodu bir araya getirdim:

/**
 * 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
Kodu biraz güncellemek isteyebilirsiniz. Ayrılan dizinin curFilters.length + 1 boyutunda olması gerekir ve newFilters oluşturduktan sonra, yeni atanan diziye "this" ayarlamamışsınızdır. InputFilter newFilters [] = yeni InputFilter [curFilters.length + 1]; System.arraycopy (curFilters, 0, yeniFilters, 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

Bunu başarabilmenin başka bir yolu da XML dosyasına aşağıdaki tanımı eklemektir:

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

Bu, EditTextwidget'ın maksimum uzunluğunu 6 karakterle sınırlar.


6

Gönderen material.io , sen kullanabilirsiniz TextInputEditTextbirlikte 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>

Düzenlenebilir bir parola EditText yapılandırabilirsiniz:

şifre örneği

Veya metin uzunluğunu sayaçlı / sayaçsız olarak sınırlayabilirsiniz:

karşı örnek

Bağımlılık:

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

6

XML

android:maxLength="10"

Programlı:

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

Not: dahili olarak, EditText ve TextView XML'deki değerini ayrıştırır android:maxLengthve InputFilter.LengthFilter()uygulamak için kullanın .

Bkz: TextView.java # L1564


2

Bu, Uzunluk filtresinin diğer filtrelerle birlikte yaşamasına izin veren özel bir EditText Sınıfıdır. Tim Gallagher'ın Cevabı sayesinde (aşağıda)

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

xml basit yolu:

android:maxLength="4"

u xml edit-text içinde 4 karakter ayarlamak gerekiyorsa, bunu kullanın

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

2

Bu iyi çalışıyor ...

android:maxLength="10"

bu yalnızca 10karakterleri kabul eder .


2

Java için bunu programlı olarak deneyin :

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

1
myEditText.setFilters(new InputFilter[] {new InputFilter.LengthFilter(CUSTOM_MAX_LEN)});
Aşağıdaki

1

Bir çok iyi çözüm görmüştüm, ancak aşağıdakileri içeren daha eksiksiz ve kullanıcı dostu bir çözüm olarak düşündüğüm bir şey vermek istiyorum:

1, Sınır uzunluğu.
2, daha fazla giriş varsa, tost tetiklemek için bir geri arama verin.
3, İmleç ortada veya kuyrukta olabilir.
4, Kullanıcı bir dize yapıştırarak giriş yapabilirsiniz.
5, Her zaman taşma girişini atın ve kökenini koruyun.

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

Ne yapamadım, kullanıcı geçerli girişin bir bölümünü vurgulamak ve çok uzun bir dize yapıştırmak için deneyin, vurgulamak nasıl geri yükleneceğini bilmiyorum.

Örneğin, maksimum uzunluk 10 olarak ayarlanmıştır, kullanıcı '12345678' girmiştir ve '345' seçeneğini vurgu olarak işaretleyin ve sınırlamayı aşacak bir '0000' dizesi yapıştırmaya çalışın.

Başlangıç ​​durumunu geri yüklemek için edit_text.setSelection (start = 2, end = 4) kullanmaya çalıştığımda sonuç, başlangıç ​​noktasını değil, sadece 2 boşluk '12 345 678 'olarak ekler. Birinin bunu çözmesini istiyorum.


1

android:maxLength="10"EditText içinde kullanabilirsiniz . (Burada sınır en fazla 10 karakterdir)


0

Kotlin:

edit_text.filters += InputFilter.LengthFilter(10)

ZTE Blade A520garip bir etkisi var. 10'dan fazla sembol yazdığınızda (örneğin 15), EditTextilk 10'u gösterir, ancak diğer 5 simge görünür değildir ve erişilemez. Ancak ile sembolleri sildiğinizde Backspace, önce sağ 5 sembolü siler ve sonra kalan 10'u kaldırır. Bu davranışın üstesinden gelmek için bir çözüm kullanın :

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

veya bu:

android:inputType="textNoSuggestions"

ya da şu önerileriniz varsa:

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

xml basit yolu:

android:maxLength="@{length}"

programlı olarak ayarlamak için aşağıdaki işlevi kullanabilirsiniz

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()]));
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.