MaxLength attribute on EditText not working as expected across xml and java
This may have been answered already, but I cannot find it on SO.
I have a very simple requirement: Limit the length of characters in the EditText.
I am using tag maxLength
in xml for this. The weird thing is that if the length of the entered text exceeds the specified limit, the text cannot be deleted by pressing the backspace with the soft keyboard. The entered text remains in the EditText field. After closing and reopening the softkey, the text becomes "deleteable".
<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 behavior.
I added an InputFilter to see what's going on here. The result, as described, will be the same without the 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);
}
During check-in, I see it source
will remain the same if the value is maxLength
exceeded, but Spanned dest
will change the way it should, by removing the text characters by pressing backspace.
Now what's going on here? This is a bug or indeed the default behavior. Because if the user enters their text and the limit is exceeded, they have no chance of being corrected.
Edit:
Sandeep Kumar's suggested method using Java code to set maxLength produces the same result.
et.setFilters(new InputFilter[]{new InputFilter.LengthFilter(5)});
By the way, I am using Android API 4.4.2 and SDK 23.0.2.
source to share
What worked for me was to use the bounding Textwatcher as below and use textNoSuggestions as 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();
}
}
}
...
An example of how to use a textWatcher
mFirstNameET.addTextChangedListener(new LengthTextWatcher(35));
AND
android:inputType="textNoSuggestions"
source to share