Android EditText maxLength позволяет пользователю вводить больше
Я уже установил атрибут maxLength для виджета EditText в файле макета xml и ограничивает отображение символов.
Но он по-прежнему позволяет пользователю нажимать больше букв на клавиатуре, а обратная ссылка удаляет эти дополнительные нажатия, а не последнюю букву на дисплее.
Я считаю, что это не так, как должно быть. Нажатие клавиш после достижения предела должно прекратить принимать больше ввода, даже если оно не отображается.
Любое исправление на этом?
Обновление
На основе приведенного ниже ответа для многострочного EditText добавьте также атрибут textMultiLine.
android:inputType="textFilter|textMultiLine"
Ответы
Ответ 1
Надеюсь, это поможет
Ответ 2
К сожалению, следующий ответ не работает. Тем не менее, это помогло нам выяснить, что ошибка, упомянутая Poly Bug, не воспроизводится, если ввод начинается с числа.
Вы можете использовать TextWatcher
для прослушивания изменений EditText
и запретить пользователю вводить слишком много символов в поле. Для меня работает следующий код:
final int maxLength = 10;
EditText editText = (EditText) findViewById(R.id.my_edittext_id);
editText.addTextChangedListener(new TextWatcher() {
@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.length() >= maxLength) s.delete(maxLength, s.length());
}
});
В afterTextChanged
код сравнивает длину вставленного текста с максимальной длиной maxLength
и удаляет все лишние символы.
Вы можете заменить все стандартные классы EditText
следующим классом, чтобы использовать слушатель в сочетании с атрибутом maxLength
XML:
public class MyMaxLengthEditText extends EditText {
public static final String XML_NAMESPACE_ANDROID = "http://schemas.android.com/apk/res/android";
private final int mMaxLength;
public MyMaxLengthEditText(Context context) {
super(context, null);
mMaxLength = -1;
}
public MyMaxLengthEditText(Context context, AttributeSet attrs) {
super(context, attrs);
mMaxLength = attrs.getAttributeIntValue(XML_NAMESPACE_ANDROID, "maxLength", -1);
addTextChangedListener(new TextWatcher() {
@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.length() >= mMaxLength) s.delete(mMaxLength, s.length());
}
});
}
}
Ответ 3
Вы можете использовать InputFilter
InputFilters могут быть привязаны к Editables для ограничения изменений которые могут быть сделаны с ними.
Xml
<EditText
android:id="@+id/edit_Text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Класс Java
int maxLengthofYourEditText = 5; // Set Your Limit
edit_TextObj.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLengthofYourEditText)});
Ответ 4
Я также столкнулся с этой ситуацией, когда имел ряд полей, содержащих 1 символ (обычный пин-код).
Мой выбор основан на ответе @jmeinke.
Создайте макет, содержащий несколько EditText
с android:maxLength="2"
(мы введем 1 символ в любой из них и перейдем к другому EditText
. Странно, но на некоторых телефонах приведенный ниже код работает даже для maxLength = 1).
class YourTextWatcher(
private val prevEdit: EditText?,
private val currEdit: EditText,
private val nextEdit: EditText?,
private val method: () -> Unit
) : TextWatcher {
override fun afterTextChanged(s: Editable?) {
if (s.isNullOrEmpty()) {
prevEdit?.requestFocus()
} else {
if (s.length > 1) {
if (currEdit.selectionEnd > 1) {
// If stand on second position of EditText and enter new symbol,
// will move to next EditText copying second symbol.
val secondSymbol = s.substring(1, 2)
nextEdit?.setText(secondSymbol)
}
// Remove second symbol.
s.delete(1, s.length)
}
nextEdit?.requestFocus()
nextEdit?.setSelection(nextEdit.length(), nextEdit.length())
method()
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
}
Затем для всех EditText
сделайте следующее:
currEdit.addTextChangedListener(
YourTextWatcher(prevEdit, currEdit, nextEdit) { yourMethodToValidateText() })
Вместо prevEdit, currEdit, nextEdit устанавливает ваши элементы управления EditText
. Например, для первого:
edit1.addTextChangedListener(
YourTextWatcher(null, edit1, edit2) { yourMethodToValidateText() })
yourMethodToValidateText() - это метод, который проверяет введенные символы. Например, вы можете проверить, заполнены ли все EditText
.
Это решение имеет ошибку, когда вы пытаетесь нажать BackSpace в пустом EditText
. Ничего не происходит, вы не перейдете на предыдущий EditText
. Вы можете поймать BackSpace в View.OnKeyListener, но он может пересекаться с TextWatcher. Также я не проверял ситуацию, когда копировал и вставлял текст в EditText
, забыл проверить, что происходит, когда выделите текст в EditText
и нажмите Delete.