Ryan Ryan - 3 months ago 9
Android Question

Execute Searches While Typing

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.

Answer

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;
}
Comments