2

I am implementing addTextChangedListener on an EditText.

 tagNameEditText.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) {
                    last_text_edit = System.currentTimeMillis();
                    searchStringFilter = s.toString();
                    h.removeCallbacks(input_finish_checker);
                    already_queried = false;
                    h.postDelayed(input_finish_checker, idleTime);
                    // getFilter().filter(s.toString());
                }

                @Override
                public void afterTextChanged(Editable s) {
                }
            });

Problem is whenever text changes in EditText it is called multiple times. But i want to call the OnTextChanged() only once after the text changes. Is there any way to achieve this ?. Any help is appreciated :)

Awadesh
  • 3,530
  • 2
  • 20
  • 32

4 Answers4

1

Even I faced the similar problem. What i did was, i put a time say 1 second or 2 second. So i called the filter whenever user takes this much time/pause in typing.

refer to -

https://stackoverflow.com/a/12143050/1320616

Community
  • 1
  • 1
Ankit Aggarwal
  • 5,317
  • 2
  • 30
  • 53
  • Hii ankit I think this solution is best , but i am getting runtime exception: can't create handler inside thread. Please help me – Awadesh Dec 24 '15 at 06:26
  • you might be doing some ui operations inside the run() method. you cannot perform ui operations inside a worker thread. can you post your code inside run() method – Ankit Aggarwal Dec 24 '15 at 06:33
0

This method will be called each time the text changes, so that means EACH time a new letter is added to the EditText.

It is working by design.

You can use View.OnFocusChangeListener to ONLY notify you when the user changes the focus away from the EditText. (You will have to filter when the hasFocus boolean is now false, to get 'moving away from' the edittext view.

This would allow you to only get called 'once' per "Edit Session".

mawalker
  • 2,072
  • 2
  • 22
  • 34
  • Hii @mawalker Actually I am implementing Filterable interface to search the items in a listview. For Query i am using Edittext, so focus is not changing. In order to optimize the search I detect whether user has stopped typing or not. – Awadesh Dec 24 '15 at 05:54
0

Move your code to afterTextChanged method

@Override
public void afterTextChanged(Editable s) {
    last_text_edit = System.currentTimeMillis();
    searchStringFilter = tagNameEditText.getText().toString();
    h.removeCallbacks(input_finish_checker);
    already_queried = false;
    h.postDelayed(input_finish_checker, idleTime);
}

onTextChanged : This means when you start typing, like you want to write "sports" then this will call on each and every character, like it will call when you pressed "s" then again "p" then "o" and so on...

afterTextChanged : This will call when you stop typing, it will calls after you completely wrote "sport".

Bhargav Thanki
  • 4,924
  • 2
  • 37
  • 43
0

as per your comment on the first answer, there should be a separate button for search; if you do not want to filter for substrings...

I would suggest you should invoke the filtering on the strings >n in size.. like

@Override
public void onTextChanged(CharSequence s, int start, int before, 
    int count) {
    .
    .
    if size of s is > n:
        cancel prev filtering
        do fresh filtering on s
}

or; you can do filtering on afterTextChanged after a delay of 1 or 2 sec.. you can use Timer and TimerTask..

Rupesh
  • 3,415
  • 2
  • 26
  • 30
  • there is no separate button because i am using expandable listview. Search Edittext is part of a list in expandable listview – Awadesh Dec 24 '15 at 06:28
  • why not go with the `>n` approach.. I don't see any harm in invoking filter multiple times; (if the filter is fetching data over n/w or db you just need to cancel the prev fetching..) or just go with approach of `Timer` as suggested above in the answer by @ankit aggarwal... – Rupesh Dec 24 '15 at 06:44