在文本更改侦听器上的android

inr*_*rob 234 java android onchange textview

我有一种情况,那里有两个领域.field1field2.改变后我想做的就是空的field2,field1反之亦然.所以最后只有一个字段有内容.

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("");
   }
  });
Run Code Online (Sandbox Code Playgroud)

如果我只附加addTextChangedListener,它工作正常field1,但当我为两个字段执行时,应用程序崩溃.显然是因为他们试图无限期地互相改变.一旦field1改变它field2在此时 清除field2就会改变,所以它会清除field1等等......

有人建议任何解决方案?

use*_*315 408

您可以添加检查以仅清除字段中的文本不为空时(即长度不是0时).

field1.addTextChangedListener(new TextWatcher() {

   @Override
   public void afterTextChanged(Editable s) {}

   @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(s.length() != 0)
        field2.setText("");
   }
  });

field2.addTextChangedListener(new TextWatcher() {

   @Override
   public void afterTextChanged(Editable s) {}

   @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(s.length() != 0)
         field1.setText("");
   }
  });
Run Code Online (Sandbox Code Playgroud)

TextWatcher 这里的文档.

另外请尊重命名约定.


Fra*_*cis 23

Kotlin 中只需使用KTX 扩展功能:( 它使用TextWatcher

yourEditText.doOnTextChanged { text, start, count, after -> 
        // action which will be invoked when the text is changing
    }
Run Code Online (Sandbox Code Playgroud)


进口core-KTX

implementation "androidx.core:core-ktx:1.2.0"
Run Code Online (Sandbox Code Playgroud)


Bob*_*tor 17

我知道这已经过时了,但总有一天会有人再遇到这个问题.

我有一个类似的问题,我会在EditText上调用setText,当我不想要它时会调用onTextChanged.我的第一个解决方案是在调用setText()之后编写一些代码以撤消侦听器所造成的损坏.但那并不是很优雅.在做了一些研究和测试后,我发现使用getText().clear()以与setText("")大致相同的方式清除文本,但由于它没有设置文本,因此不调用监听器,因此解决了我的问题.我将所有的setText("")调用切换到getText().clear(),我不再需要绷带了,所以也许这也可以解决你的问题.

试试这个:

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.getText().clear();
   }
  });

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.getText().clear();
   }
  });
Run Code Online (Sandbox Code Playgroud)


iHu*_*ulk 10

如果您使用Kotlin进行Android开发,那么您可以TextChangedListener()使用以下代码添加:

myTextField.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) {}
    })
Run Code Online (Sandbox Code Playgroud)


Bur*_*lek 6

我为此编写了自己的扩展程序,对我很有帮助。(科特林)

你只能这样写:

editText.customAfterTextChanged { editable -> 
    //You have accessed the editable object. 
}
Run Code Online (Sandbox Code Playgroud)

我的扩展:

fun EditText.customAfterTextChanged(action: (Editable?)-> Unit){
    this.addTextChangedListener(object : TextWatcher {
       override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
       override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
       override fun afterTextChanged(editable: Editable?) {
        action(editable)
    }
})}
Run Code Online (Sandbox Code Playgroud)


小智 5

我也遇到了同样的问题,并不断获取堆栈满异常,我提供了以下解决方案。

    edt_amnt_sent.addTextChangedListener(new TextWatcher() {    
        @Override
        public void afterTextChanged(Editable s) {

            if (skipOnChange)
                return;

            skipOnChange = true;
            try {
                //method
                }
            } catch (NumberFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                skipOnChange = false;
            }
        }
    });

    edt_amnt_receive.addTextChangedListener(new TextWatcher() {


        @Override
        public void afterTextChanged(Editable s) {

            if (skipOnChange)
                return;

            skipOnChange = true;
            try 
            {
                //method
            } catch (NumberFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                skipOnChange = false;
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

最初声明为boolean skipOnChange = false;

  • “堆栈已满”我认为你的意思是堆栈溢出;) (2认同)

小智 5

您还可以使用 hasFocus() 方法:

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

我在大学作业中对此进行了测试,以便在用户输入时转换温标。工作完美,而且更简单。


Eur*_*nes 5

答案有点晚了,但这是一个可重用的解决方案:

/**
 * 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);
}
Run Code Online (Sandbox Code Playgroud)

因此,使用上面的方法时,setText()TextWatcher中发生的任何调用都不会导致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) {
    }
}
Run Code Online (Sandbox Code Playgroud)


Cod*_*ker 5

var filenameText = findViewById(R.id.filename) as EditText
filenameText.addTextChangedListener(object : TextWatcher {
    override fun afterTextChanged(s: Editable?) {
        filename = filenameText.text.toString()
        Log.i("FileName: ", filename)
    }
    
    override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
Run Code Online (Sandbox Code Playgroud)