0

When I set a TextWatcher to a EditText like so:

editText1.addTextChangedListener(watcher);

Interface methods onTextChanged, afterTextChanged and beforeTextChanged are fired, no matter if the EditText contains text or not.

I assumed that these methods are called only after a text change after binding. Can I prevent this behaviour? Have I made a logical error that is resulting in this behaviour?

Thanks

Edit:

I setText() before addTextChangedListener.

call stack:

DalvikVM[localhost:8600]    
Thread [<1> main] (Suspended)   
    <VM does not provide monitor information>   
    EditText(TextView).sendOnTextChanged(CharSequence, int, int, int) line: 7875    
    EditText(TextView).setText(CharSequence, TextView$BufferType, boolean, int) line: 3488  
    EditText(TextView).setText(CharSequence, TextView$BufferType) line: 3341    
    EditText.setText(CharSequence, TextView$BufferType) line: 90    
    EditText(TextView).setText(CharSequence) line: 3316 
    EditText(TextView).onRestoreInstanceState(Parcelable) line: 3216    
    EditText(View).dispatchRestoreInstanceState(SparseArray) line: 10079    
    ...
alexgophermix
  • 4,189
  • 5
  • 32
  • 59
user1324936
  • 2,187
  • 4
  • 36
  • 49

1 Answers1

2

Those methods should not fire when you just call addTextChangedListener(TextWatcher). Likely you are just calling setText() or otherwise modifying the text programatically.


This is the source code of android.widget.TextView.addTextChangedListener:

public void addTextChangedListener(TextWatcher watcher) {
    if (mListeners == null) {
        mListeners = new ArrayList<TextWatcher>();
    }
    mListeners.add(watcher);
}
Oleg Vaskevich
  • 12,444
  • 6
  • 63
  • 80
  • I setText() before addTextChangedListener. Is this problematic? – user1324936 Jan 06 '13 at 15:02
  • Before? It shouldn't be... if you remove that line does it still get called? It's just that there must be a reason for the `TextWatcher` to be fired. If you can't find why, you can set a boolean flag after you're done setting up the UI and while it's false initially just return from the `TextWatcher`'s methods. Perhaps you're restoring state or something after `addTextChangedListener`? – Oleg Vaskevich Jan 06 '13 at 15:55
  • i only setTxt in my onCreate method. if i dont set it nothing happens! I have a ViewPager. The issue happens only if I scroll back to a previously loaded page. I set the TextWatcher to null onDestroyView and create a new one if the Fragment reloads. I checked that the old one gets deleted before onCreateView. – user1324936 Jan 06 '13 at 20:11
  • The problem is here - setting the `TextWatcher` to null won't remove it from the `EditText`! It's already attached to it internally - see [this question](http://stackoverflow.com/questions/6270484/how-to-remove-all-listeners-added-with-addtextchangedlistener). You can thus either implement this custom `EditText` or just use the a flag to disregard the event. For example: 1) set flag to return from `TextWatcher`, 2) call `setText()` as needed, 3) unset the flag – Oleg Vaskevich Jan 06 '13 at 23:33
  • the problem is that editText's onRestoreInstanceState calls the setText. See my call stack. Why I dont know. – user1324936 Jan 07 '13 at 19:26
  • problem is that fragments does not get deleted (memory leak that im aware of). he reuses the previous view and its elements when scrolling back and sets the text – user1324936 Jan 07 '13 at 22:06
  • Yup, exactly. Once you add a `TextChangedListener` it will stay that way, and `TextWatcher` will internally call `setText()`. Usually this isn't a problem because the views are destroyed but your case with the view pager is special... you need a flag as such. – Oleg Vaskevich Jan 07 '13 at 23:04
  • How should I set this flag? I cannot distinguish if setText comes from user interaction or from onRestoreInstanceState. – user1324936 Jan 08 '13 at 18:17
  • Set the flag to allow the `TextWatcher` to work within your `onPostCreate()`. – Oleg Vaskevich Jan 08 '13 at 20:41