50

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

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 в настоящее время сосредоточено.

+1

Возможный дубликат [Как использовать Single TextWatcher для нескольких EditTexts?] (Http://stackoverflow.com/questions/5702771/how-to-use-single-textwatcher-for-multiple-edittexts) – 2015-10-27 04:04:37

+1

@SkyKelsey Ответ, который вы написали, на самом деле создает несколько экземпляров TextWatcher, поэтому я считаю, что это не идеальный ответ на то, что было задано OP, поскольку мой вопрос заключается в идентификации каждого EditText в методах интерфейса TextWatcher. – 2015-10-29 12:48:26

+0

https://github.com/henrychuangtw/AutoInsertEditText – HenryChuang 2017-01-18 02:12:12

ответ

66

Предложенное решение в @Sebastian Roth's answer не один экземпляр 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); 
75

Я хотел бы сделать это следующим образом:

@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) { 
    } 
} 
+4

Интересная идея, но это означает, что у вас есть отдельный наблюдатель текста для каждого EditText. – ArtOfWarfare 2012-12-03 19:41:30

+10

Этот ответ не является «Единым TextWatcher для нескольких EditTexts». Это 3 экземпляра одного класса TextWatcher. Таким образом, 3 отдельных TextWatchers контролируют 3 EditTexts. – breceivemail 2012-12-08 12:07:45

+1

@breceivemail, один класс, 3 экземпляра. Согласитесь, это сложно, когда люди не указывают свой тип объекта. Его цель заключалась в том, чтобы написать код только один раз, так что это так. – SparK 2013-10-24 13:23:41

1

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

Аналогично решению Hashcode выше вы можете просто проверить, если getText()==s. Вместо того, чтобы хранить все свои элементы управления или findViewById несколько раз, вы можете просто сканировать дерево контента самостоятельно один раз для элемента управления, который имеет 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.

1

Глобальный Один класс для всех видов деятельности.

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) { 

     } 
    } 
11

используя идею "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 
} 

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

2

Еще один способ обойти это, чтобы добавить 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; 
     } 
    } 
0

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

8

--EDIT--

Если вы хотите использовать только afterTextChanged сравнить editables:

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

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

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) { 

} 
3

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

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

    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)); 
    
1

После нескольких способов достижения этого, я нахожу правильный путь, используя EditText.isFocused(), чтобы отличать друг друга.Например:

private class OnTextChangedListener implements 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) { 

    } 

    @Override 
    public void afterTextChanged(Editable editable) { 
     if (edtName.isFocused()) { 
      //do something 
     } else if (edtEmail.isFocused()) { 
      //do something 
     } else if (edtContent.isFocused()) { 
      //do something 
     } 
    } 
} 
0

просто сравнить хэш-коды в EditText и строки, как с помощью хэш-код() метод

@Override 
public void afterTextChanged(Editable s) { 

    if (editext.getText().hashCode() == s.hashCode()){ 
     type1Total(type1List); 
    } 

} 
0

Это то, что я сделал ...

private TextWatcher textWatcher = 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) { 

     if (editText1.getText().length() > 0 
       && editText2.getText().length() > 0 
       && editText3.getText().length() > 0) { 

      button.setEnabled(true); 
     } else { 

      button.setEnabled(false); 
     } 

    } 

    @Override 
    public void afterTextChanged(Editable s) { 

    } 

Затем только что добавленный TextWatcher для каждого EditText в методе onCreate & также сохранил кнопку setEnabled (false) по умолчанию здесь.

button.setEnabled(false); 

    editText1.addTextChangedListener(textWatcher); 
    editText2.addTextChangedListener(textWatcher); 
    editText3.addTextChangedListener(textWatcher); 
Смежные вопросы