我创建了一个可搜索的活动。 现在,我想补充一点,从网络服务采取的搜索建议。 我想这些建议是异步的。 据添加自定义的建议我需要重写的查询方法,做我的建议的搜索,建立自己的MatrixCursor并返回。 但是这就是问题所在,我对得到的建议是一个异步地一个请求。 所以当结果回来从查询方法的范围内净出来的一面。
Answer 1:
下面是搜索查看与建议从网络服务(我使用改造)来的一个示例:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_search_activity, menu);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.search));
final CursorAdapter suggestionAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
null,
new String[]{SearchManager.SUGGEST_COLUMN_TEXT_1},
new int[]{android.R.id.text1},
0);
final List<String> suggestions = new ArrayList<>();
searchView.setSuggestionsAdapter(suggestionAdapter);
searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
@Override
public boolean onSuggestionSelect(int position) {
return false;
}
@Override
public boolean onSuggestionClick(int position) {
searchView.setQuery(suggestions.get(position), false);
searchView.clearFocus();
doSearch(suggestions.get(position));
return true;
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
MyApp.autocompleteService.search(newText, new Callback<Autocomplete>() {
@Override
public void success(Autocomplete autocomplete, Response response) {
suggestions.clear();
suggestions.addAll(autocomplete.suggestions);
String[] columns = {
BaseColumns._ID,
SearchManager.SUGGEST_COLUMN_TEXT_1,
SearchManager.SUGGEST_COLUMN_INTENT_DATA
};
MatrixCursor cursor = new MatrixCursor(columns);
for (int i = 0; i < autocomplete.suggestions.size(); i++) {
String[] tmp = {Integer.toString(i), autocomplete.suggestions.get(i), autocomplete.suggestions.get(i)};
cursor.addRow(tmp);
}
suggestionAdapter.swapCursor(cursor);
}
@Override
public void failure(RetrofitError error) {
Toast.makeText(SearchFoodActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
Log.w("autocompleteService", error.getMessage());
}
});
return false;
}
});
return true;
}
Answer 2:
看来,请求建议内容提供者未在UI线程上运行,无论如何,根据这样的回答: https://stackoverflow.com/a/12895381/621690 。 如果你可以改变你的HTTP请求,你可以简单地把它叫做查询方法内部阻塞。 可能有助于(也许自定义的)监听中断或其他信号,以阻止不必要的请求。
另一种选择 - 如果你不想更改已同步(比如,如果你正在使用Robospice)任何请求类 - 应该只返回MatrixCursor参考,并填充它以后。 所述AbstractCursor类已经实现了观察者模式和在变化的情况下发出通知。 如果搜索系统是听它应该处理数据的任何变化。 我还没有实现我自己,所以我不能确定它会制定出很好的作为,因为我想象它。 (看一看CursorLoader的来源更多的灵感。)
而且,不管怎么说,这不就是一个光标整点? 否则,我们可以简单地返回与数据的列表。
更新:对于我来说,使用MatrixCursor没有发挥出来。 相反,我已经实现了其他两种解决方案:
- 在ArrayAdapter的自定义子类,本身使用过滤器的自定义子类组合使用AutoCompleteTextField。 该方法
Filter#performFiltering()
其余与向远程服务同步调用重写)异步调用和UI线程没有被阻塞。 使用带有SearchableActivity和定制ArrayAdapter(不包括自定义过滤器)的SearchWidget。 当搜索意图进来,远程请求开始(Robospice),当它通过回调回来,我叫下面的自定义方法对我
ArrayAdapter<Tag>
的子类:public void addTags(List<Tag> items) { if (items != null && items.size() > 0) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { super.setNotifyOnChange(false); for (Tag tag : items) { super.add(tag); } super.notifyDataSetChanged(); } else { super.addAll(items); } } }
此方法需要触发的适配器,从而在搜索结果列表上的通知的照顾。
Answer 3:
我已经找到了解决这个最接近的事,是利用ContentProvider的和做的网络请求, Query
您的供应商(即使这违背了最佳做法)的方法,结果,你可以创建一个MatrixCursor
因为它显示这里和这里 。
我仍然在寻找像使用其他选项SyncAdapter
,这似乎压倒一点用都没有其他地方那样只显示建议的目的。
另一种选择,我采取异步做到这一点是使用AutoCompleteTextView,这样你可以创建一个自定义适配器,在那里你可以实现getFilter
因为它是在显示功能这个答案 。