我想为多个TextWatcher
字段实现EditText
接口。目前我正在使用:
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
}
然而,这工作正常,但我正在寻找其他方法,以便我可以明确指出EditText
字段当前所关注的SoftKeyboard
字段。
答案 0 :(得分:84)
@Sebastian Roth's answer中的建议解决方案不是某些TextWatcher
EditTexts
的一个实例。对于n EditTexts
,它是该类的一个类和n个实例。
每个EditText都有自己的Spannable。 TextWatcher
的事件将此Spannable作为s
参数。我检查他们的hashCode(每个对象的唯一ID)。 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);
答案 1 :(得分:82)
我会这样做:
@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) {
}
}
答案 2 :(得分: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
}
好吧,让我知道你的想法。
答案 3 :(得分:11)
<强> - 编辑 - 强>
如果您只想使用afterTextChanged比较editables:
@Override
public void afterTextChanged(Editable editable) {
if (editable == mEditText1.getEditableText()) {
// DO STH
} else if (editable == mEditText2.getEditableText()) {
// DO STH
}
}
答案 4 :(得分:7)
我使用这个解决方案:
添加返回侦听器的方法:
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));
答案 5 :(得分: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;
}
}
答案 6 :(得分: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
。
答案 7 :(得分:1)
所有活动的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) {
}
}
答案 8 :(得分: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) {
}
答案 9 :(得分: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
}
}
}
答案 10 :(得分:0)
您始终可以将TextWatcher
定义为addTextChangedListener
方法的参数。这样,每个编辑文本都可以有多个定义。
答案 11 :(得分:0)
只需使用 hashCode()方法比较edittext和字符串的哈希码
@Override
public void afterTextChanged(Editable s) {
if (editext.getText().hashCode() == s.hashCode()){
type1Total(type1List);
}
}
答案 12 :(得分: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&amp;默认情况下也保持按钮setEnabled(false)。
button.setEnabled(false);
editText1.addTextChangedListener(textWatcher);
editText2.addTextChangedListener(textWatcher);
editText3.addTextChangedListener(textWatcher);
答案 13 :(得分:0)
您可以执行此操作以获取编辑文本的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);
}
答案 14 :(得分:0)
如果您使用的是Kotlin,扩展功能将完成此工作。
例如,我们需要将TextWatcher添加到editText1
和editText2
创建这样的扩展功能,
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
}
}
}
}
)
}
然后只需将文本监视器添加到EditTexts中
editText1.addTextWatcher()
editText2.addTextWatcher()
答案 15 :(得分:0)
我做了这样的事情,只有一个 TextWatcher
类来控制来自 EditText
或 Activity
的 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)
}
}
然后在您的 Activity
或 Fragment
中,您需要注册尽可能多的 EditText
,如下所示,而且我已经使用 Data Binding 来获取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) {
}
})
}