I have a problem with implementing searchview showing its results for data coming from a server. I currently use an AsyncTask so that I don't block the UI. Here's how I implemented it:
searchView.setOnQueryTextListener(new OnQueryTextListener() {
@Override
public boolean onQueryTextChange(String query) {
if (query.length() > 0) {
new GetSearchByNameResultTask(searchView).execute(query);
} else {
return false;
}
return true;
}
@Override
public boolean onQueryTextSubmit(String arg0) {
// TODO Auto-generated method stub
return false;
}
});
GetSearchByNameResultTask
class GetSearchByNameResultTask extends AsyncTask<String, Void, String> {
private SearchView searchView;
public GetSearchByNameResultTask(SearchView searchView) {
this.searchView = searchView;
}
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
return WebRequestHelper.getInfo(params[0]);
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
AppLog.d(TAG, "Result search: " + result);
Gson gson = new Gson();
searchResponseList = gson.fromJson(result, new TypeToken<List<Info>>() {
}.getType());
loadHistory(searchView, searchResponseList);
// TODO: search adapter
}
}
loadHistory() code:
private void loadHistory(SearchView searchView, List<AppInfo> searchResponse) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
searchView.setSuggestionsAdapter(null);
// Cursor
String[] columns = new String[] { "_id", "text" };
Object[] temp = new Object[] { 0, "default" };
MatrixCursor cursor = new MatrixCursor(columns);
final List<Info> items = searchResponse;
for (int i = 0; i < items.size(); i++) {
temp[0] = i;
temp[1] = items.get(i).getName();
cursor.addRow(temp);
}
CursorAdapter ca = new AppListSearchAdapter(this, cursor, items);
new AsyncQueryResult(cursor,ca).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
// SearchView
searchView.refreshDrawableState();
searchView.setSuggestionsAdapter(ca);
searchView.setOnSuggestionListener(new OnSuggestionListener() {
@Override
public boolean onSuggestionSelect(int position) {
// TODO Auto-generated method stub
return false;
}
});
}
}
Problem Everything runs alright. I'm getting the search results. But I have a problem updating the views. Probably best explained with an example:
Data:
Hell Hello Helicopter
text in search: Hel
Result:
Hello World Hello Helicopter
text in search: Hell
Hell Hello [extra empty space]
the extra empty space is my problem. The "listview" doesn't get updated to fit the results until I type 'Hello'
I forgot to answer this question.
I managed to fix this issue, although it was a bit of a hack on my part. Here's what I did:
@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
searchAdapter = new SearchAdapter(this, cursor, false);
mSearchView.setSuggestionsAdapter(searchAdapter );
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
searchAdapter.notifyDataSetChanged();
}
}, 200);
//Reload fragment to show list
}
This would force to refresh the search view's adapter. The new Handler().postDelayed() was the key here.
Hope this solution helps.