Для работы с элементов EditText
когда-нибудь вам придётся организовывать слежение за вводов пользователя. Есть стандартный OnKeyListener
, но он как-то странно работает 0_о. Но обо всём попорядку.
OnKeyListener
Можно на EditText
повесить OnKeyListener
, который будет отслеживать нажатия на виртуальной клавиатуре. Как-то так:
((EditText)findViewById(R.id.resultNumericSystemTE)). setOnKeyListener(new View.OnKeyListener(){ public boolean onKey(View v, int keyCode, KeyEvent event){ return false; } } );
Вроде всё нормально, в keyCode
у нас ID нажатой клавиши. По сути всё, можем принимать нажатую кнопку или отменять ввод. Вот только это событие прокает почему-то лишь на кнопки по манипулированию: удаление символа, Enter и т.д.
TextWatcher
Ок, ищем другое решение. Находим интересный класс TextWatcher
. Пробуем повесить на наш EditText:
TextWatcher inputTW = new TextWatcher() { public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after){ } public void onTextChanged(CharSequence s, int start, int before, int count) { } }; ((EditText)findViewById(R.id.MyTE)).addTextChangedListener(inputTW);
Супер! Теперь можно что-то сделать с EditText до и после нажатия. Вот только есть одна проблемка — нету ссылки на сам EditText
внутри TextWatcher
. Можно конечно обращаться внутри обработчика глобально, типо:
public void afterTextChanged(Editable s) { EditText et = (EditText)findViewById(R.id.MyTE); }
Да, будет всё отлично работать, но тогда при написании обработчиков на все EditText
придётся дублировать кучу кода. А хотелось бы где-то прописать один раз этот, так сказать, шаблон поведения, а потом юзать его.
Свой TextWatcher
И да, можно *__* В Java есть implements — это дополнение к определению класса, реализующего некоторый интерфейс(ы). Создаём свой класс. Как пример, хотим, чтобы в EditText
юзер не мог ввести больше 2 символов:
public class TextWatcherP implements TextWatcher { public EditText editText; public TextWatcherP(EditText et){ super(); editText = et; } public void afterTextChanged(Editable s) { if(editText.getText().length() == 3){ editText.setText(editText.getText().subSequence(0, editText.getText().length()-1)); } } public void beforeTextChanged(CharSequence s, int start, int count, int after){ } public void onTextChanged(CharSequence s, int start, int before, int count) { } }
По сравнению с базовым классом, наш в конструкторе принимает ссылку на EditText
, что устраняет проблему описанную выше. Использовать же просто:
EditText et = (EditText)findViewById(R.id.MyTE) TextWatcherP inputTextWatcher= new TextWatcherP(et); et.addTextChangedListener(inputTextWatcher);