74

我想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

4

16 回答 16

96

@Sebastian Roth 的回答中建议的解决方案不是TextWatcherfor some的一个实例EditTexts。对于 n 来说,它是一个类和该类的 n 个实例EditTexts

每个 EditText 都有自己的 Spannable。TextWatcher的事件有这个 Spannable 作为s参数。我检查他们的 hashCode (每个对象的唯一 ID)。myEditText1.getText() 返回 Spannable。所以如果myEditText1.getText().hashCode()等于s.hashCode()它就意味着s属于myEditText1

因此,如果您想拥有TextWatcherfor some的一个实例,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);
于 2012-12-09T12:04:28.990 回答
88

我会这样做:

@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) {
    }
}
于 2010-11-26T08:15:38.227 回答
13

我使用这个解决方案:

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

    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));
    
于 2017-03-10T18:57:40.483 回答
12

使用“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 
}

好吧,让我知道你的想法。

于 2013-12-24T15:29:40.617 回答
12

- 编辑 -

如果您只想使用 afterTextChanged 比较可编辑项:

@Override
public void afterTextChanged(Editable editable) {
    if (editable == mEditText1.getEditableText()) {
        // DO STH
    } else if (editable == mEditText2.getEditableText()) {
        // DO STH
    }
}
于 2014-06-18T09:37:19.803 回答
2

另一种方法是添加OnClickListenerEditText设置一个全局变量,如下所示

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;
        }
    }
于 2014-05-12T13:50:33.903 回答
2

我将其实现为:

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

}
于 2017-02-28T11:33:20.797 回答
2

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
        }
    }
}
于 2017-10-10T07:42:01.037 回答
1

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

与上面的 hashCode 解决方案类似,您只需检查 if 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;
   }
}

当然你也可以使用findTextViewinsidebeforeTextChangedonTextChanged.

于 2013-05-12T00:27:40.283 回答
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) {

        }
    }
于 2013-10-15T05:33:45.350 回答
1

您可以这样做以获取编辑文本的 id。它未经测试,但让我知道它是否有效。

//setting textWatcher for the editText
textWatcher(owner_name);


public void textWatcher(final EditText editText){

    TextWatcher watcher = new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

           if(editText.getId()==R.id.your_id){
             //Do something
           }   
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
          if(editText.getId()==R.id.your_id){
          //Do something
          }
        }

        @Override
        public void afterTextChanged(Editable s) { }
    };

    editText.addTextChangedListener(watcher);
}
于 2018-10-06T14:02:43.387 回答
0

您始终可以将其定义TextWatcheraddTextChangedListener方法的参数。这样您可以为每个编辑文本有多个定义。

于 2014-05-30T07:37:24.337 回答
0

只需使用hashCode()方法比较编辑文本和字符串的哈希码

@Override
public void afterTextChanged(Editable s) {

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

}
于 2017-11-23T13:02:05.143 回答
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 添加到 onCreate 方法中的每个 EditText 并在此处默认保留按钮 setEnabled(false) 。

button.setEnabled(false); 

    editText1.addTextChangedListener(textWatcher);
    editText2.addTextChangedListener(textWatcher);
    editText3.addTextChangedListener(textWatcher);
于 2017-12-21T11:40:54.083 回答
0

如果您使用的是 Kotlin,扩展功能将完成这项工作。例如,我们需要将 TextWatcher 添加到editText1editText2

像这样创建一个扩展函数,

 fun EditText.addTextWatcher() {
        this.addTextChangedListener(
                object : TextWatcher {
                    override fun afterTextChanged(s: Editable?) {

                    }

                    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

                    }

                    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                        // you do some common operations here

                        when (this@addTextWatcher) {
                            editText1 -> {
                                // do something for editText1
                            }
                            editText2 -> {
                                // do something for editText2
                            }
                        }
                    }
                }
        )
    }

然后像这样将 textwatcher 添加到 EditTexts

editText1.addTextWatcher()
editText2.addTextWatcher()
于 2020-07-16T05:06:15.830 回答
0

我已经做了这样的事情,只有一个TextWatcher班级可以控制EditText来自ActivityOR的尽可能多的班级Fragment

您需要首先创建一个MultiTextWatcher类,如下所示

class MultiTextWatcher {

    private var callback: TextWatcherWithInstance? = null

    fun setCallback(callback: TextWatcherWithInstance): MultiTextWatcher {
        this.callback = callback
        return this
    }


    fun registerEditText(editText: EditText): MultiTextWatcher {
        editText.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
                callback!!.beforeTextChanged(editText, s, start, count, after)
            }

            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
                callback!!.onTextChanged(editText, s, start, before, count)
            }

            override fun afterTextChanged(editable: Editable) {
                callback!!.afterTextChanged(editText, editable)
            }
        })

        return this
    }

     interface TextWatcherWithInstance {
        fun beforeTextChanged(editText: EditText, s: CharSequence, start: Int, count: Int, after: Int)

        fun onTextChanged(editText: EditText, s: CharSequence, start: Int, before: Int, count: Int)

        fun afterTextChanged(editText: EditText, editable: Editable)
    }
}

然后在你的ActivityorFragment中,你需要像下面那样注册尽可能多EditText的,而且我已经使用数据绑定来获取XML视图的引用,你可以使用你的方式。

 private fun setTextWatchers() {
        MultiTextWatcher()
            .registerEditText(binding.etCompanyAddress)
            .registerEditText(binding.etCompanyIntro)
            .registerEditText(binding.etCompanyName)
            .registerEditText(binding.etCompanyPhone)
            .setCallback(object : MultiTextWatcher.TextWatcherWithInstance {
                override fun beforeTextChanged(editText: EditText, s: CharSequence, start: Int, count: Int, after: Int) {
                }

                override fun onTextChanged(editText: EditText, s: CharSequence, start: Int, before: Int, count: Int) {
                    when (editText) {
                        binding.etCompanyAddress -> {
                            //do your logic here
                        }
                        binding.etCompanyPhone -> {
                            //do your logic here and so on
                        }
                    }
                }

                override fun afterTextChanged(editText: EditText, editable: Editable) {

                }
            })
    }
于 2021-01-30T18:16:26.347 回答