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不是某些EditTexts
的TextWatcher
实例。 它是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; } }
当然你也可以在beforeTextChanged
和onTextChanged
里面使用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 } } }