Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

addTextChangedListener and onTextChanged are always called when Android Fragment loads

I have an EditText in an Android Fragment. I attach addTextChangedListener to it in the onCreateView method. Within the addTextChangedListener I have an onTextChanged method. By logging, I can see that every time the Fragment is loaded, onTextChanged is called. Why would this be? I only want it to be called when the user actually changes the text in the EditText. Here's my code:

@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.detailfragment, container, false);
    final EditText notes = (EditText)view.findViewById(R.id.stitchnotes);
notes.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) {
            Edited = true;
        }
    });

    return view;
}

I found this post and this post and I'm wondering if I should move my code to onResume. However, as you can see from the above code, I need access to the LayoutInflater and ViewGroup passed to onCreateView in order to access the EditText; however, onResume doesn't normally have access to these items. Should I be using onResume? How do I handle the issue with the LayoutInflater and ViewGroup?

-----------------Further Information----------------------

I used Tyler's answer to solve the problem of how to use onResume, but onTextChanged is still being called when I first open the Fragment. Can someone explain why? Here's my modified code:

private EditText notes;
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.detailfragment, container, false);
    notes = (EditText)view.findViewById(R.id.stitchnotes);
    return view;
}

@Override
public void onResume() {
    super.onResume();
    notes.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) {
            Edited = true;
            Log.w("onTextChanged","Here");
        }
    });
}

<EditText
        android:id="@+id/stitchnotes"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="left"
        android:hint="@string/hint"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:inputType="text"
        android:visibility="invisible"
        android:textSize="30dip" />

The moment I open the Fragment, Edited is set to true and the LogCat is written to. I don't want this. I want Edited to be set to true only when the user actually types something in the EditText. What am I doing wrong?

like image 557
Melanie Avatar asked Feb 11 '14 21:02

Melanie


People also ask

What is the use of TextWatcher in android?

EditText is used for entering and modifying text. While using EditText width, we must specify its input type in inputType property of EditText which configures the keyboard according to input. EditText uses TextWatcher interface to watch change made over EditText.

What is EditText in android?

A EditText is an overlay over TextView that configures itself to be editable. It is the predefined subclass of TextView that includes rich editing capabilities.


2 Answers

I got same problem but in adapter. The above solution is working fine for the direct child of the view but in list view adapter I have problem. Finally I found the solution with focus change.

 editQty.setTag(false);
    editQty.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            editQty.setTag(true);
        }
    });
    editQty.addTextChangedListener(new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            if (!s.toString().equals("") && (Boolean) editQty.getTag()) {
               // Do your Logic here
                }
            }
        }
    });
like image 100
Raja Peela Avatar answered Oct 15 '22 04:10

Raja Peela


Make your EditText a member of the class. Or, make the View a member of the class and call findViewById later.

public class MyFragment extends Fragment {

    private EditText notes;

    @Override
    public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle     savedInstanceState) {
        View view = inflater.inflate(R.layout.detailfragment, container, false);
        notes = (EditText)view.findViewById(R.id.stitchnotes);
        // your other stuff
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        notes.setText("Now I can access my EditText!");
    }

    ...
like image 8
Tyler MacDonell Avatar answered Oct 15 '22 04:10

Tyler MacDonell