5

I have a working searchable Activity that queries a remote database upon submitting input in the ActionBar's android.support.v7.widget.SearchView (entering "Go" on the soft keyboard). This works fine, but I would ultimately like to query the database each time the SearchView's text changes via adding or removing a character. My initialization code of the SearchView is below.

SearchFragment.java (child fragment of the searchable Activity mentioned above)

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.menu_search, menu);

    // Get the searchable.xml data about the search configuration
    final SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
    SearchableInfo searchInfo = searchManager.getSearchableInfo(getActivity().getComponentName());
    // Associate searchable configuration with the SearchView
    mSearchView = (SearchView) menu.findItem(R.id.menu_item_search).getActionView();
    mSearchView.setSearchableInfo(searchInfo);
    mSearchView.requestFocus();
    mSearchView.onActionViewExpanded();
    getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            mSearchListAdapter.clear();
            return false;
        }

        @Override
        public boolean onQueryTextChange(String query) {
            mSearchListAdapter.clear();
            // Execute search ...
            return false;
        }
    });
}

I imagine the work needs to be done within the onQueryTextChange(String query) method above, but I'm not sure what needs to be called. I thought of invoking the SearchManager's startSearch instance method, but that doesn't appear to be best practice. Does anyone have any experience with type-to-search and would be willing to share an efficient solution?

UPDATE:

MainActivity.java (the searchable Activity)

@Override
protected void onNewIntent(Intent intent) {
    setIntent(intent);

    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        // Handle the search for a particular musical object
        final SearchFragment searchFragment = (SearchFragment) getFragmentManager().findFragmentByTag(SearchFragment.TAG);
        String query = intent.getStringExtra(SearchManager.QUERY);

        mWebService.searchTracks(query, new Callback<Pager>() {
            @Override
            public void success(Pager results, Response response) {
                Log.d(TAG, "Search response received.");
                searchFragment.updateItems(results);
            }
            @Override
            public void failure(RetrofitError retrofitError) {
                Log.e(TAG, "Search response failed: " + retrofitError.toString());
            }
        });

The above search interface design is what's recommended by the Android team at Google.

Ryan
  • 3,414
  • 2
  • 27
  • 34

4 Answers4

2

So far, the only solution that I have come across after reading through several pages of documentation is simply sending an intent with the Intent.ACTION_SEARCH action and the current query from the SearchView to start the searchable Activity whenever the SearchView's text changes. Keep in mind that this probably isn't the best practice in terms of the SearchManager design, but it works. I'll revisit this approach at a later date and report back here if I come across anything new.

@Override
public boolean onQueryTextChange(String query) {
     mSearchListAdapter.clear();
     if (!query.isEmpty()) {
          Intent searchIntent = new Intent(getActivity(), MainActivity.class);
          searchIntent.setAction(Intent.ACTION_SEARCH);
          searchIntent.putExtra(SearchManager.QUERY, query);
          startActivity(searchIntent);
     }
     return false;
}
Ryan
  • 3,414
  • 2
  • 27
  • 34
1

A TextWatcher should be what you are looking for. It also offers for executing code before or after the text has changed.

http://developer.android.com/reference/android/text/TextWatcher.html

 When an object of a type is attached to an Editable, its methods will be called when the text is changed.
toidiu
  • 965
  • 2
  • 12
  • 25
0

This is the perfect solution for the issue you are looking for.

See this this will help you... Android Action Bar SearchView as Autocomplete?

Community
  • 1
  • 1
Rohit5k2
  • 17,948
  • 8
  • 45
  • 57
  • I'm not looking to provide auto-complete search suggestions. I'm simply looking for a way to execute a search query to a remote database each time a character is typed into or removed from the ```SearchView```. – Ryan Dec 22 '14 at 19:59
  • Would you fire a api call to another remote server for that? – Rohit5k2 Dec 22 '14 at 20:02
  • Yep. It would require an API call each time the ```SearchView```'s text is changed. I'm basically looking for the _correct_ way to invoke the Searchable ```Activity```'s search service when the query's text changes. – Ryan Dec 22 '14 at 20:13
  • Seems AsyncTask is what you are looking for. You can make your api calls in method "onQueryTextChange(String query)" and when response comes back update the adapter of SearchView with the response – Rohit5k2 Dec 22 '14 at 20:18
  • I'm using the search interface design recommended by Google's Android team. It involves the use of a _searchable_ activity that handles an ```ACTION_SEARCH``` intent. The query is then pulled from the ```SearchManager```. This is where my async API call takes place. My original post is updated to reflect this. I'm looking for the correct way to invoke my searchable Activity besides just starting an intent from my ```SearchFragment``` due to the fact that other actions most likely take place in the background that I don't have control of by just starting an intent. – Ryan Dec 22 '14 at 20:46
  • Although I never tried this on my own but this seems to be explaining it nicely. This might help you http://developer.android.com/guide/topics/search/search-dialog.html It explains where to make your api calls – Rohit5k2 Dec 22 '14 at 20:51
0

In case you're still looking for a better solution: I just found this answer to a similar question, which uses

searchView.setOnQueryTextListener(this);

which is exactly what you want.

Community
  • 1
  • 1
user2483352
  • 113
  • 4