TextWatcher用于多个EditText

我想为多个EditText字段实现TextWatcher接口。 目前我正在使用:

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

然后重写我的Activity中的方法:

 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 } 

但是,这工作正常,但我正在寻找其他方式,以便我可以明确地确定SoftKeyboard目前在哪个EditText字段集中。

在@Sebastian Roth的答案中build议的解决scheme不是某些EditTextsTextWatcher实例。 它是n类EditTexts一个类和n个实例。

每个EditText都有自己的Spannable。 TextWatcher的事件有这个Spannable作为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)创build一个新的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)创build和使用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 compare编辑器:

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

我使用这个解决scheme:

  • 添加返回侦听器的方法:

     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并设置一个全局variables,如下所示

 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; } } 

是的,您可以使用存储TextView的自定义TextWatcher多个实例。 ( TextView实际上是具有addTextChangedListener的类。)

类似于上面的hashCode解决scheme,您可以检查是否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; } } 

当然你也可以在beforeTextChangedonTextChanged里面使用findTextView

全球一类的所有活动。

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方法的参数。这样,​​您可以为每个编辑文本定义多个定义。

尝试几种方法来实现这一点,我find正确的方式使用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 } } }