我有一个情况,有两个领域。Field1和field2。我想要的 当field1被改变时,要做的是空field2,反之亦然。所以只有在最后 一个字段上有内容。

field1 = (EditText)findViewById(R.id.field1);
field2 = (EditText)findViewById(R.id.field2);

field1.addTextChangedListener(new TextWatcher() {

   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) {
      field2.setText("");
   }
  });

field2.addTextChangedListener(new TextWatcher() {

   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) {
     field1.setText("");
   }
  });

它工作得很好,如果我附加addTextChangedListener到field1,但当 我对两个字段都这么做,应用程序崩溃了。显然是因为他们想要改变 无限地相互联系。一旦field1改变,此时它就会清除field2 Field2被更改,因此它将清除field1,以此类推……

谁能给点建议吗?


当前回答

我们可以在编辑文本之前删除字段的TextWatcher,然后在编辑文本之后将其添加回来。

将field1和field2的文本监视器声明为单独的变量,并为它们命名:例如field1

private TextWatcher Field_1_Watcher = new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    @Override
    public void afterTextChanged(Editable s) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

};

然后使用它的名称添加该监视程序: field1. addtextchangedlistener (Field_1_Watcher)用于field1,和 field2. addtextchangedlistener (Field_2_Watcher)用于field2

在修改field2文本之前,删除TextWatcher: field2.removeTextChangedListener (Field_2_Watcher) 修改文本: field2.setText (" ")

然后将TextWatcher添加回来: field2.addTextChangedListener (Field_2_Watcher)

对另一个字段做同样的处理

其他回答

这个回答有点晚了,但这里有一个可重复使用的解决方案:

/**
 * An extension of TextWatcher which stops further callbacks being called as 
 * a result of a change happening within the callbacks themselves.
 */
public abstract class EditableTextWatcher implements TextWatcher {

    private boolean editing;

    @Override
    public final void beforeTextChanged(CharSequence s, int start, 
                                                    int count, int after) {
        if (editing)
            return;

        editing = true;
        try {
            beforeTextChange(s, start, count, after);
        } finally {
            editing = false;
        }
    }

    protected abstract void beforeTextChange(CharSequence s, int start, 
                                                     int count, int after);

    @Override
    public final void onTextChanged(CharSequence s, int start, 
                                                int before, int count) {
        if (editing)
            return;

        editing = true;
        try {
            onTextChange(s, start, before, count);
        } finally {
            editing = false;
        }
    }

    protected abstract void onTextChange(CharSequence s, int start, 
                                            int before, int count);

    @Override
    public final void afterTextChanged(Editable s) {
        if (editing)
            return;

        editing = true;
        try {
            afterTextChange(s);
        } finally {
            editing = false;
        }
    }

    public boolean isEditing() {
        return editing;
    }

    protected abstract void afterTextChange(Editable s);
}

因此,当使用上述方法时,在TextWatcher中发生的任何setText()调用都不会导致TextWatcher再次被调用:

/**
 * A setText() call in any of the callbacks below will not result in TextWatcher being 
 * called again.
 */
public class MyTextWatcher extends EditableTextWatcher {

    @Override
    protected void beforeTextChange(CharSequence s, int start, int count, int after) {
    }

    @Override
    protected void onTextChange(CharSequence s, int start, int before, int count) {
    }

    @Override
    protected void afterTextChange(Editable s) {
    }
}

在Kotlin中简单使用KTX扩展函数: (它使用TextWatcher)

yourEditText.doOnTextChanged { text, start, count, after -> 
        // action which will be invoked when the text is changing
    }

进口core-KTX:

implementation "androidx.core:core-ktx:1.2.0"

你用这个 我已经提供了textchangelistner的最新方法

edMsg.addTextChangedListener(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) {
                
                if (i2 == 0){
                    ////Edit text blanked
                } 
                
                String msg = charSequence.toString();/// your text on changed in edit text
                
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });

在onCreate方法中动态添加背景:

getWindow().setBackgroundDrawableResource(R.drawable.background);

也从XML中删除背景。

你也可以使用hasFocus()方法:

public void onTextChanged(CharSequence s, int start,
     int before, int count) {
     if (Field2.hasfocus()){
         Field1.setText("");
     }
   }

我在大学作业中测试了这个方法,在用户输入温标时转换温标。效果很好,而且简单多了。