8

in an android activity, i first recover the text in an EditText and add then a TextWatcher to it.

private static int WC = 0;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("TextWatcherTest", "onCreate:\t" +CLASS_NAME);
setContentView(R.layout.main);

EditText et = (EditText)findViewById(R.id.editText);
Log.e("TextWatcherTest", "Set text xyz");
et.setText("xyz");

et.addTextChangedListener(new TextWatcher() {
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) { }
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
    @Override
    public void afterTextChanged(Editable s) {
        Log.e("TextWatcherTest", "afterTextChanged:\t" +s.toString());
    }
});
}

but when i run the activity, the afterTextChanged method is called even if the Watcher itself is added after setting the text. so the log output is something like

onCreate:    LifecycleMain
Set text xyz
// screen rotation
onCreate:    LifecycleMain
Set text xyz
afterTextChanged:    xyz    2

the counter in the TextWatcher shows that the watcher that is called is the one that was added AFTER the text was set in the EditText. any ideas why that happens and how i can prevent that?

SimonSays
  • 10,867
  • 7
  • 44
  • 59

2 Answers2

8

Solution is to move your addTextChangedListener to onPostCreate method. all will be solved.

darakok
  • 149
  • 2
  • 4
  • 2
    was convenient (in a Fragment) for me to check "isResumed()" and only respond to onTextChanged in this case, seemed to do the trick – hmac Jun 06 '16 at 12:46
1

This definitely must be happening. You are setting text when savedinstanceState is not null (meaning your previous object states are saved).

I think that this happens because you added the TextWatcher to your EditText in the onCreate method, and next time onCreate gets called (e.g. after a configuration change) then it finds that the TextWatcher has already been added to the EditText.

If you want to check for this situation, put this before your condition:

if(savedInstanceState == null){
    Log.e("savedInstance state is null", "no text");
    et.setText("No text");
}

In this case, if you call setText on your EditText, then afterTextChanged(Editable s) will not be called.

Kevin Coppock
  • 133,643
  • 45
  • 263
  • 274
N-JOY
  • 10,344
  • 7
  • 51
  • 69
  • not really. it is indeed true that it works the very first time the activity is created, but the EditText is every time a new instance without any watcher attached to it. i simplified the code and added a counter to the watcher: – SimonSays Mar 01 '11 at 07:06
  • have u defined editText et as static? if yes this might be the reason. and as u mention it works f9 for the first time, then the prob is definitely that new instance of ediText is not getting created each time – N-JOY Mar 01 '11 at 07:13
  • sorry, it updated my comment before i finished it. i updated the code above now. i simplified it and added a counter for the TextWatcher. what you can see is that the problem not appears the very first time the activity is created, but the second time. BUT, the second TextWatcher instance is called, not the first one. also the EditText is always a new instance without any watcher attached. and no; the EditText is not defined static. – SimonSays Mar 01 '11 at 07:29
  • "removeTextChangedListener" use this method just below u defined EditText and then try 2 setText. – N-JOY Mar 01 '11 at 07:51
  • i tried that already - no change, still the same. and as i said before, the TextWatcher that gets called is the one that i add AFTER setting the text, not the one from the activity before. – SimonSays Mar 01 '11 at 07:57
  • 1
    ok, i've got it. too stupid of me! the TextWatcher is called not because of the text that i am setting, but because android itself also recovers the text in the EditText after a screen rotation between the onStart() and the onResume() methods. so i have to add the watcher in the onResume() method which makes not much sense, but then it works at least. – SimonSays Mar 01 '11 at 08:13
  • Do you also need to remove the watchers in the onStart(), so they don't get fired during the wierd restart sequence? – John Watson Oct 27 '11 at 05:41