I want to return search suggestions for the ActionBar SearchView from a ContentProvider that asynchronously loads these suggestions from a webservice using Volley. However, I am struggling to find a way to notify the dropdown of changes to the MatrixCursor. As of now, the suggestions retrieved from the webservice are only visible when typing another character, because this is when the previously updated cursor is returned. Is there an elegant way to either notify the DropdownView or force a requery after the initial query has been completed?
SearchSuggestionProvider:
@Override
@DebugLog
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
switch (uriMatcher.match(uri)) {
case SEARCH_SUGGEST:
String searchQuery = uri.getLastPathSegment().toLowerCase();
Log.d(TAG, "searchQuery: " + searchQuery);
if (searchQuery.equals("search_suggest_query") || searchQuery.length() < 3) {
return mAsyncCursor;
}
if (mRequest != null && !mRequest.hasHadResponseDelivered()) {
mRequest.cancel();
}
String url = API.buildUri(API.PRODUCT, searchQuery, SEARCH_QUERY_LIMIT, SEARCH_QUERY_MIN, 0);
mRequest = new GsonRequest<>(url, Product[].class, null, new Response.Listener<Product[]>() {
@Override
@DebugLog
public void onResponse(Product[] products) {
onAsyncResponse(products);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
// nothing
}
});
AppController.getInstance().addToRequestQueue(mRequest, TAG);
// return an empty cursor as long as no async response is returned
return mAsyncCursor;
default:
throw new IllegalArgumentException(uri.toString());
}
}
/**
* Updates the current cursor with a new cursor when we get a response
* @param products
*/
@DebugLog
private void onAsyncResponse(Product[] products) {
MatrixCursor newCursor = createCursor();
for (int i = 0; i < products.length; i++) {
Product product = products[i];
mAsyncCursor.addRow(new String[] {
String.valueOf(product.getId()), // _ID
null, // todo SUGGEST_COLUMN_ICON_1
product.getName(), // SUGGEST_COLUMN_TEXT_1
null, // todo SUGGEST_COLUMN_TEXT_2
String.valueOf(product.getId()) // SUGGEST_COLUMN_INTENT_DATA_ID
});
}
mAsyncCursor = newCursor;
}
private MatrixCursor createCursor() {
return new MatrixCursor(SEARCH_SUGGEST_COLUMNS, SEARCH_QUERY_LIMIT);
}