Я видел много хороших решений, но я хотел бы дать то, что я считаю более полным и удобным решением, которое включает в себя:
1, предельная длина.
2, Если ввод больше, дайте обратный вызов, чтобы вызвать тост.
3, Курсор может быть посередине или хвостом.
4, Пользователь может вводить, вставляя строку.
5, Всегда отбрасывать ввод переполнения и сохранятьпроисхождение.
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();
}
}
}));
Что мне не удалось сделать, так это то, что если пользователь выделил часть текущего ввода и попытался вставить очень длинную строку, я не знаю, как восстановить выделение.
Например, максимальная длина установлена на 10, пользователь ввел «12345678» и пометил «345» как выделение, и попытайтесь вставить строку «0000», которая превысит ограничение.
Когда я пытаюсь использовать edit_text.setSelection (start = 2, end = 4) для восстановления исходного состояния, в результате просто вставляется 2 пробела как '12 345 678', а не выделение источника.Я бы хотел, чтобы кто-нибудь решил это.