1

I have a custom autocomplete function that fetches results from a remote server in the onQueryTextChange method based on the input. It is similar to JQuery autocomplete plugin that fetches results via Ajax on keyup listener.

However it is quite a waste to fetch results when the user is just pressing backspace to delete the input text he has previously entered because the returned results are usually the same in my situation. How can I prevent that from happening?

I have tried using a global boolean variable backKeyPressed to detect whether the user is pressing backspace and check it in onQueryTextChange but setOnKeyListener doesn't even work at all. No logs for "onKey" have even been shown in the logcat.

Would anyone have any ideas on how to detect if backspace key is pressed in onQueryTextChange?

private boolean backKeyPressed = false;
private Runnable autoCompleteRunnable;
private Handler = new Handler(Looper.getMainLooper());
private String enteredSuggestion = "";

public boolean onCreateOptionsMenu(Menu menu) {

    /****************/

    searchView.setOnKeyListener(new View.OnKeyListener() {
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event) {

                    if (keyCode == KeyEvent.KEYCODE_DEL) {
                        backKeyPressed = true;
                    }else{
                        backKeyPressed = false;
                    }
                    Log.d("onKey",Boolean.toString(backKeyPressed));
                    return false;
                }
            });

            searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextSubmit(String query) {
                    /**Some functions**/
                    return false;
                }

                @Override
                public boolean onQueryTextChange(final String inputText) {
                    handler.removeCallbacks(autoCompleteRunnable);

                    if(enteredSuggestion.trim().equals(inputText.trim())){
                       Log.d("response_on_duplicated","true");
                       return false;
                    }

                    if(backKeyPressed == true){
                        Log.d("response_onKey","No");
                        return false;
                    }
                    autoCompleteRunnable = new Runnable() {
                        public void run() {
                            fetchSuggestionFromRemoteServer(inputText);
                        }
                    };
                    handler.postDelayed(autoCompleteRunnable, 3000);

                    enteredSuggestion = inputText;

                    return false;
                }
            });
}
RedGiant
  • 4,444
  • 11
  • 59
  • 146
  • if the user presses the backspace usually you should get the more results, is'n it? so whats the reason in that? – pskink Apr 03 '16 at 04:39
  • Are you using soft keyboards? because OnKeyListener doesn't work on it. http://stackoverflow.com/q/4886858/2252016 – 1binary0 Apr 03 '16 at 04:49
  • @1binary0, ah yes, I'm using soft keyboards – RedGiant Apr 03 '16 at 04:52
  • @pskink,Thanks, I would think about it. Does ACTV require building a list of suggestions beforehand? I have about a thousand entries in the remote database. My current approach only fetches five entries at a time based on the user's input. – RedGiant Apr 03 '16 at 05:13
  • see [this](http://stackoverflow.com/a/19860624/2252830) – pskink Apr 03 '16 at 05:20
  • with this approach you can cache returned data from `runQuery` to use it for future requests when you expect no data changes, note that when you type quite fast it is not called every time the `ACTV` input changes – pskink Apr 03 '16 at 05:36

1 Answers1

3

If you can't get the backspace key. You could use a simple work around.

You could store the length of your query string when a server call is made. Then next time in onQueryTextChange you can check whether the length of inputText is less than the length of server call string. If it is less then update the server call length with this new length, because if you don't next time if a user removes 2 characters and adds a 1 new character, your code will not make a server call. If you want a pseudo-code, do let me know.

Eric B.
  • 4,622
  • 2
  • 18
  • 33
  • I have quickly added some code based on your suggestion. See variable `enteredSuggestion` which is used to store the previous input value. If it is the same as the current input value, it will not make a server call. Next I'll work on comparing the lengths of them. Just a rough idea. Please feel free to give me some suggestions. – RedGiant Apr 03 '16 at 04:52
  • Yes that's great! Just one thing, in your `onQueryTextChange`, you have used this assignment. `enteredSuggestion = itemTitle;`. Shouldn't it be `enteredSuggestion = inputText;`? – Eric B. Apr 03 '16 at 04:56