Intereting Posts
AlertDialog с селектором Андроид (ART) с ошибкой JNI DETECTED ERROR IN APPLICATION: jarray – неверная справочная таблица недействительного стека или неверная ссылка Ошибка Gradle Sync не удалось найти ограничение-макет: 1.0.0-alpha2 Есть ли способ поместить поле EditText / input в виджетов рабочего стола? Задать заголовок панели инструментов «Системные службы, недоступные для операций до onCreate ()« Сообщение об ошибке? В выставлении счетов не работает после обновления – Google Store Получение ошибки разрешения при импорте проекта в студию android, Не удается загрузить класс 'org.codehaus.groovy.runtime.typehandling.ShortTypeHandling' Как изменить стиль MediaRouteButton в ActionBar? Применить плагин: «android» или применить плагин: «com.android.application» Android: Как вы можете получить фреймбуфер (скриншот) на корневом устройстве? Смена анимации ActionBar? Как скачать pdf-файл в Android? Как увеличить / увеличить часть изображения Custom Progress Dialog Android

TextWatcher для нескольких EditText

Я хочу реализовать интерфейс TextWatcher для нескольких полей EditText . В настоящее время я использую:

 text1.addTextChangedListener(this); text2.addTextChangedListener(this); 

Затем переопределение методов в моей деятельности:

 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) { // do some operation on text of text1 field // do some operation on text of text2 field } 

Однако это работает нормально, но я ищу другие способы, чтобы я мог явно определить, в каком поле EditText находится SoftKeyboard .

Solutions Collecting From Web of "TextWatcher для нескольких EditText"

Предлагаемое решение в ответе @Sebastian Roth – это не один экземпляр TextWatcher для некоторых EditTexts . Это один класс и n экземпляров этого класса для n EditTexts .

Каждый EditText имеет свой собственный Spannable. TextWatcher имеют этот параметр Spannable as s . Я проверяю их hashCode (уникальный идентификатор каждого объекта). MyEditText1.getText () возвращает Spannable. Итак, если myEditText1.getText().hashCode() равен s.hashCode() это означает, что s принадлежит myEditText1

Поэтому, если вы хотите иметь один экземпляр TextWatcher для некоторых EditTexts вы должны использовать это:

 private TextWatcher generalTextWatcher = new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (myEditText1.getText().hashCode() == s.hashCode()) { myEditText1_onTextChanged(s, start, before, count); } else if (myEditText2.getText().hashCode() == s.hashCode()) { myEditText2_onTextChanged(s, start, before, count); } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { if (myEditText1.getText().hashCode() == s.hashCode()) { myEditText1_beforeTextChanged(s, start, count, after); } else if (myEditText2.getText().hashCode() == s.hashCode()) { myEditText2_beforeTextChanged(s, start, count, after); } } @Override public void afterTextChanged(Editable s) { if (myEditText1.getText().hashCode() == s.hashCode()) { myEditText1_afterTextChanged(s); } else if (myEditText2.getText().hashCode() == s.hashCode()) { myEditText2_afterTextChanged(s); } } }; 

а также

 myEditText1.addTextChangedListener(generalTextWatcher); myEditText2.addTextChangedListener(generalTextWatcher); 

Я бы сделал это так:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); EditText e = new EditText(this); e.addTextChangedListener(new CustomTextWatcher(e)); } private class CustomTextWatcher implements TextWatcher { private EditText mEditText; public CustomTextWatcher(EditText e) { mEditText = e; } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } public void afterTextChanged(Editable s) { } } 

Используя идею «CustomTextWatcher», я сделал это

1) Вырезал новый интерфейс TextWatcherListener:

 public interface TextWatcherExtendedListener extends NoCopySpan { public void afterTextChanged(View v, Editable s); public void onTextChanged(View v, CharSequence s, int start, int before, int count); public void beforeTextChanged(View v, CharSequence s, int start, int count, int after); } 

2) Создал и использовал EditTextExtended вместо EditText (в моем случае):

 public class EditTextExtended extends EditText { private TextWatcherExtendedListener mListeners = null; public EditTextExtended(Context context) { super(context); } public EditTextExtended(Context context, AttributeSet attrs) { super(context, attrs); } public EditTextExtended(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void addTextChangedListener(TextWatcherExtendedListener watcher) { if (mListeners == null) { mListeners = watcher; } } public void removeTextChangedListener(TextWatcherExtendedListener watcher) { if (mListeners != null) { mListeners = null; } } void sendBeforeTextChanged(CharSequence text, int start, int before, int after) { if (mListeners != null) { mListeners.beforeTextChanged(this, text, start, before, after); } } void sendOnTextChanged(CharSequence text, int start, int before,int after) { if (mListeners != null) { mListeners.onTextChanged(this, text, start, before, after); } } void sendAfterTextChanged(Editable text) { if (mListeners != null) { mListeners.afterTextChanged(this, text); } } } 

3) Итак, где вам нужно написать этот код:

 myEditTextExtended.addTextChangedListener(this) //Let implement TextWatcherExtendedListener methods 

4) использовать их:

 @Override public void onTextChanged(View v, CharSequence s, int start, int before, int count) { //Tested and works //do your stuff } @Override public void beforeTextChanged(View v, CharSequence s, int start, int count, int after) { //not yet tested but it should work } @Override public void afterTextChanged(View v, Editable s) { //not yet tested but it should work } 

Ну, дайте мне знать, что вы думаете.

–РЕДАКТИРОВАТЬ–

Если вы хотите использовать только afterTextChanged, сравните редактируемые файлы:

 @Override public void afterTextChanged(Editable editable) { if (editable == mEditText1.getEditableText()) { // DO STH } else if (editable == mEditText2.getEditableText()) { // DO STH } } 

Я использую это решение:

  • Добавить метод, который возвращает слушатель:

     private TextWatcher getTextWatcher(final EditText editText) { return new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { // do what you want with your EditText editText.setText("blabla"); } @Override public void afterTextChanged(Editable editable) { } }; } 
  • Добавьте слушателя в несколько EditText, вы также можете передать другие параметры:

     editText1.addTextChangedListener(getTextWatcher(editText1)); editText2.addTextChangedListener(getTextWatcher(editText2)); editText3.addTextChangedListener(getTextWatcher(editText3)); 

Еще один способ – добавить OnClickListener в EditText и установить глобальную переменную, как указано ниже

 EditText etCurrentEditor;//Global variable @Override public void onClick(View v) { // TODO Auto-generated method stub if(v instanceof EditText){ etCurrentEditor=(EditText)v; } } 

Используйте этот etCurrentEditor в качестве ссылки на редактируемый EditText

 @Override public void afterTextChanged(Editable editable) { // TODO Auto-generated method stub switch (etCurrentEditor.getId()) { case R.id.EDITTEXTID: break; default: break; } } 

Да, вы можете использовать несколько экземпляров настраиваемого TextWatcher которые хранят TextView . ( TextView на самом деле является классом, который имеет addTextChangedListener .)

Подобно решению hashCode выше, вы можете просто проверить, есть ли getText()==s . Вместо того, чтобы хранить все свои элементы управления или findViewById несколько раз, вы можете просто сканировать дерево контента один раз для CharSequence управления, имеющего CharSequence .

 public TextView findTextView(View v, CharSequence s) { TextView tv; ViewGroup vg; int i, n; if (v instanceof TextView) { tv = (TextView) v; if (tv.getText()==s) return(tv); } else if (v instanceof ViewGroup) { vg = (ViewGroup) v; n = vg.getChildCount(); for(i=0;i<n;i++) { tv = findTextView(vg.getChildAt(i), s); if (tv!=null) return(tv); } } return(null); } public void afterTextChanged(Editable s) { TextView tv=findTextView(findViewById(android.R.id.content), s); if (tv==null) return; switch(tv.getId()) { case R.id.path: break; case R.id.title: break; } } 

Конечно, вы также можете использовать findTextView внутри beforeTextChanged и onTextChanged .

Global One для всех видов деятельности.

CustomTextWatcher.java

 package org.logicbridge.freshclub.customizedItems; import android.content.Context; import android.text.Editable; import android.text.TextWatcher; public class CustomTextWatcher implements TextWatcher { private EditText mEditText; Context context; public CustomTextWatcher(EditText e, Context context) { mEditText = e; this.context = context; } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { } public void afterTextChanged(Editable s) { } } 

Я реализовал это как:

 edittext1.addTextChangedListener(this); edittext2.addTextChangedListener(this); edittext3.addTextChangedListener(this); 

а также:

 @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { if(edittext1.hasFocus()){ //text changed for edittext1 }else if(edittext2.hasFocus()){ //text changed for edittext2 }else { //text changed for edittext3 } } @Override public void afterTextChanged(Editable editable) { } 

Вы всегда можете определить TextWatcher как параметр addTextChangedListener Таким образом, вы можете иметь несколько определений для каждого текста редактирования.