Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android on Text Change Listener

I have a situation, where there are two fields. field1 and field2. All I want to do is empty field2 when field1 is changed and vice versa. So at the end only one field has content on it.

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("");
   }
  });

It works fine if I attach addTextChangedListener to field1 only, but when I do it for both fields the app crashes. Obviously because they try to change each other indefinitely. Once field1 changes it clears field2 at this moment field2 is changed so it will clear field1 and so on...

Can someone suggest any solution?

like image 852
inrob Avatar asked Dec 29 '13 11:12

inrob


People also ask

What is afterTextChanged in Android?

afterTextChanged(Editable s) This method is called to notify you that, somewhere within s , the text has been changed. abstract void. beforeTextChanged(CharSequence s, int start, int count, int after)

What is the use of TextWatcher in Android?

EditText uses TextWatcher interface to watch change made over EditText. For doing this, EditText calls the addTextChangedListener() method.

How do I use addTextChangedListener?

You should create a Listener class like so, Just modify the parameters in the constructor to accept the EditText ID you want to add a listener to. mobileNumber2. addTextChangedListener(new addListenerOnTextChange(this, mobileNumber2)); Again modify the parameters as needed.


4 Answers

You can add a check to only clear when the text in the field is not empty (i.e when the length is different than 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("");
   }
  });

Documentation for TextWatcher here.

Also please respect naming conventions.

like image 131
user2336315 Avatar answered Oct 19 '22 01:10

user2336315


In Kotlin simply use KTX extension function: (It uses TextWatcher)

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


import core-KTX:

implementation "androidx.core:core-ktx:1.2.0"
like image 41
Francis Avatar answered Oct 19 '22 02:10

Francis


I know this is old but someone might come across this again someday.

I had a similar problem where I would call setText on a EditText and onTextChanged would be called when I didn't want it to. My first solution was to write some code after calling setText() to undo the damage done by the listener. But that wasn't very elegant. After doing some research and testing I discovered that using getText().clear() clears the text in much the same way as setText(""), but since it isn't setting the text the listener isn't called, so that solved my problem. I switched all my setText("") calls to getText().clear() and I didn't need the bandages anymore, so maybe that will solve your problem too.

Try this:

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();
   }
  });
like image 26
RTHarston Avatar answered Oct 19 '22 03:10

RTHarston


If you are using Kotlin for Android development then you can add TextChangedListener() using this code:

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) {}
    })
like image 17
iHulk Avatar answered Oct 19 '22 03:10

iHulk