Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

afterTextChanged() callback being called without the text being actually changed

I have a fragment with an EditText and inside the onCreateView() I add a TextWatcher to the EditText.

Each time the fragment is being added for the second time afterTextChanged(Editable s) callback is being called without the text ever being changed.

Here is a code snippet :

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ...     myEditText = (EditText) v.findViewById(R.id.edit_text);     myEditText.addTextChangedListener(textWatcher); ... }  TextWatcher textWatcher = new TextWatcher() {      @Override     public void onTextChanged(CharSequence s, int start, int before, int count) {         searchProgressBar.setVisibility(View.INVISIBLE);     }      @Override     public void beforeTextChanged(CharSequence s, int start, int count, int after) {      }      @Override     public void afterTextChanged(Editable s) {         Log.d(TAG, "after text changed");     } } 

I also set the fragment to retain its state, and I keep the instance of the fragment in the activity.

like image 484
meh Avatar asked Dec 05 '12 10:12

meh


2 Answers

Edited solution:

As it seems the text was changed from the second time the fragment was attached because the fragment restored the previous state of the views.

My solution was adding the text watcher in the onResume() since the state was restored before the onResume was called.

@Override public void onResume() {     super.onResume();     myEditText.addTextChangedListener(textWatcher); } 

Edit As @MiloszTylenda have mentioned in the comments it is better to remove the Textwatcher in the onPause() callback to avoid leaking the Textwatcher.

@Override public void onPause() {   super.onPause();   myEditText.removeTextChangedListener(watcher); } 
like image 191
meh Avatar answered Sep 25 '22 02:09

meh


It seems that this error comes from the fact that Android SDK will call settext when view is coming alive again to recover the state of the EditText. As you can see from the extract below there is a flag that you can change on the Edittext to bypass this behavior.

    <!-- If false, no state will be saved for this view when it is being          frozen. The default is true, allowing the view to be saved          (however it also must have an ID assigned to it for its          state to be saved).  Setting this to false only disables the          state for this view, not for its children which may still          be saved. -->     <attr name="saveEnabled" format="boolean" /> 

So by adding android:saveEnabled="false" on your EditText will fix the problem and the setText will not be called when view comes to foreground.

This is what I did and problem was solved.

like image 44
z3n105 Avatar answered Sep 26 '22 02:09

z3n105