EditText中的maxLength属性无法通过xml和java按预期工作

时间:2021-08-29 00:18:59

Maybe this is already answered but I can't find it on SO.

也许这已经回答了,但我找不到它。

I have a very simple requirement: Restrict the length of characters in an EditText.

我有一个非常简单的要求:限制EditText中的字符长度。

I use the maxLength tag in xml for this. The strange thing is, if the length of the inputted text exceeds the specified limit, the text can't be deleted by pressing backspace via soft keyboard. The inputted text remains in the EditText field. After closing and reopening the soft keayboard, the text becomes "deleteable".

我在xml中使用maxLength标记。奇怪的是,如果输入文本的长度超过指定的限制,则通过软键盘按退格键无法删除文本。输入的文本保留在EditText字段中。关闭并重新打开软键盘后,文本变为“可删除”。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:maxLength="5"
        android:hint="text"/>
</RelativeLayout>

Adding this layout is enough to get the described behaviour.

添加此布局足以获得所描述的行为。

I added an InputFilter to see what's going on here. The result as described will be the same without the InputFilter!

我添加了一个InputFilter来查看这里发生了什么。如果没有InputFilter,描述的结果将是相同的!

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    EditText et = (EditText) findViewById(R.id.edit);

    InputFilter filter = new InputFilter() {
        @Override
        public CharSequence filter(CharSequence source,
                int start,
                int end,
                Spanned dest,
                int dstart,
                int dend) {

            if (source != null) {
                Log.v("edit","source = " + source.toString());
                Log.v("edit","start = " + start);
                Log.v("edit","end = " + end);
            }
            if (dest != null) { 
                Log.v("edit","dest= " + dest.toString());
                Log.v("edit","dstart = " + dstart);
                Log.v("edit","dend = " + dend);
            }
            return null;
        }
    };

    InputFilter[] oldFilters = et.getFilters();
    InputFilter[] newFilters = new InputFilter[oldFilters.length + 1];
    System.arraycopy(oldFilters, 0, newFilters, 0, oldFilters.length);
    newFilters[oldFilters.length] = filter;
    et.setFilters(newFilters);
}

While logging I can see that source will remain the same, if the maxLength is exceeded, but the Spanned dest changes the way it should, deleting the chars of text by pressing backspace.

在记录时我可以看到源将保持不变,如果超出maxLength,但是Spanned dest改变了它应该的方式,通过按退格键删除文本的字符。

Now what is going on here? Is this a bug or really the default behaviour. Because if a User types his text and the limit is exceeded, he has no chance for correction.

现在发生了什么?这是一个错误还是真正的默认行为。因为如果用户键入他的文本并超出限制,他就没有机会进行更正。

Edit:

编辑:

The suggested way by Sandeep Kumar using Java code to set the maxLength leads to the same result.

Sandeep Kumar使用Java代码设置maxLength的建议方法导致相同的结果。

 et.setFilters(new InputFilter[]{new InputFilter.LengthFilter(5)});

BTW, I'm using Android API 4.4.2 and SDK 23.0.2.

顺便说一句,我使用的是Android API 4.4.2和SDK 23.0.2。

2 个解决方案

#1


0  

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

if this code useful please vote!

如果此代码有用请投票!

#2


0  

What worked for me was to use Length restricting textwatcher as below and use textNoSuggestions as inputType

对我有用的是使用长度限制textwatcher如下所示,并使用textNoSuggestions作为inputType

public class LengthTextWatcher implements TextWatcher {

    String prevVal = "";
    int length;
    public LengthTextWatcher(int l) {
        length = l;
    }
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public void afterTextChanged(Editable s) {
        if(s != null && s.length() > 0) {
            if(s.length() > length) {
                s.clear();
                s.insert(0, prevVal);
            }
            prevVal = s.toString();
        }
    }
}

...

Sample way to apply textWatcher

应用textWatcher的示例方法

mFirstNameET.addTextChangedListener(new LengthTextWatcher(35));

And

 android:inputType="textNoSuggestions"

#1


0  

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

if this code useful please vote!

如果此代码有用请投票!

#2


0  

What worked for me was to use Length restricting textwatcher as below and use textNoSuggestions as inputType

对我有用的是使用长度限制textwatcher如下所示,并使用textNoSuggestions作为inputType

public class LengthTextWatcher implements TextWatcher {

    String prevVal = "";
    int length;
    public LengthTextWatcher(int l) {
        length = l;
    }
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public void afterTextChanged(Editable s) {
        if(s != null && s.length() > 0) {
            if(s.length() > length) {
                s.clear();
                s.insert(0, prevVal);
            }
            prevVal = s.toString();
        }
    }
}

...

Sample way to apply textWatcher

应用textWatcher的示例方法

mFirstNameET.addTextChangedListener(new LengthTextWatcher(35));

And

 android:inputType="textNoSuggestions"