我創建了一個可搜索的活動。現在,我想添加來自Web服務的搜索建議。我想要異步獲取這些建議。根據Adding Custom Suggestions我需要重寫查詢方法,做我的建議搜索,建立我自己的MatrixCursor並返回它。但這是問題,我的建議請求是異步的。所以當結果從網絡返回時,它不在查詢方法的範圍之內。Android:如何從網上異步獲取搜索建議?
回答
我發現解決這個問題的最接近的方法是使用ContentProvider並對提供者的Query
方法執行網絡請求(即使這違背了最佳實踐),結果您可以創建一個MatrixCursor
因爲它顯示here和here。
我仍在尋找其他選項,如使用SyncAdapter
,這似乎壓倒性的目的只是顯示其他地方不使用的建議。
另一種選擇是我使用一個AutoCompleteTextView來創建一個自定義適配器,您可以在其中實現getFilter
函數,如this answer所示。
似乎對建議內容提供者的請求不是在UI線程上運行,無論如何,根據這個答案:https://stackoverflow.com/a/12895381/621690。 如果你可以改變你的http請求,你可以簡單地在查詢方法中調用它。可能有助於聽取中斷或其他信號(可能是定製的)以阻止不必要的請求。
另一種選擇 - 如果你不想改變任何已經異步的請求類(就像你正在使用Robospice一樣) - 應該是返回MatrixCursor引用並在以後填充它。 AbstractCursor類已經實現了Observer模式,並在發生更改時發送通知。如果搜索系統正在監聽,它應該處理數據中的任何更改。我還沒有自己實現,所以我不能確認它會像我描繪的那樣很好地工作。 (看看CursorLoader的靈感來源。)
而且,無論如何,不是光標的整個點?否則,我們可以簡單地用數據返回一個列表。
更新: 對我而言,使用MatrixCursor無法解決問題。相反,我已經實現了其他兩種解決方案:
- 結合使用的AutoCompleteTextField與ArrayAdapter的自定義子類,本身使用過濾器的自定義子類。方法
Filter#performFiltering()
(我通過對遠程服務的同步調用重寫)被異步調用,並且UI線程未被阻止。 將SearchWidget與SearchableActivity和自定義ArrayAdapter一起使用(不使用自定義過濾器)。當搜索意圖進來,遠程請求開始(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); } } }
這種方法需要觸發的護理適配器上的通知以及搜索結果列表中的通知。
絕對是正確的想法。我試圖做到這一點,但它看起來像Android的搜索建議不聽指針的變化。 :/具體來說,我打電話給'ContentResolver.notifyChange()',但我沒有看到Android的['SuggestionAdapter'](https://android.googlesource.com/platform/frameworks/base/+/jb- release/core/java/android/widget/SuggestionsAdapter.java)調用'registerContentObserver()'。有任何想法嗎?我錯過了什麼? – ryan 2013-11-05 01:50:30
這聽起來像是正確的想法,但它沒有奏效(至少不適合我)。用我目前的解決方案更新了我的答案 – Risadinha 2013-11-05 13:12:00
感謝您的更新!那些當前的解決方案對搜索結果有意義。儘管如此,我仍然在尋找一種更新[search _suggestions_](http://developer.android.com/guide/topics/search/adding-custom-suggestions.html)的方法。我懷疑可能沒有辦法......但如果你知道的話,請讓我們知道! – ryan 2013-11-05 21:23:09
下面是搜索查看與建議,從網絡服務(我用改裝)來了一個例子:
@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;
}
您能否更好地解釋您的實施?比如,doSearch(suggestions.get(position))'方法是做什麼的?謝謝 – 2016-04-12 13:18:19
- 1. Android:如何獲得搜索建議
- 2. 如何獲取Google的搜索建議
- 3. 搜索建議android
- 4. 從網絡上搜索Android的searchview的建議
- 5. 獲取易趣的搜索建議
- 6. 無法獲取Google搜索建議API
- 7. 如何顯示Android搜索建議的多個搜索建議區域?
- 8. 高音搜索API搜索鳴叫的異步獲取
- 9. 在c#中搜索api搜索到的tweets的異步獲取
- 10. JStree異步搜索
- 11. 異步Twitter搜索
- 12. 如何從URL異步獲取內容?
- 13. 如何從WCF獲取數據(異步)?
- 14. PHP搜索建議
- 15. 如何使用WebClient從網頁獲取異步發佈數據?
- 16. 如何構建自定義搜索建議的建議表?
- 17. 如何從onQueryTextChange()獲取建議
- 18. 限制搜索建議的數量android
- 19. android搜索:自定義建議佈局
- 20. 如何從谷歌地方檢索搜索建議?
- 21. 如何顯示搜索建議
- 22. 如何搜索數據集建議?
- 23. 如何生成多詞搜索建議
- 24. 從Google搜索結果網址獲取搜索查詢
- 25. 搜索對話框搜索建議
- 26. 使用NHibernate搜索的搜索建議
- 27. 如何停止搜索我的網站時的谷歌建議
- 28. Android搜索框架,自定義搜索建議
- 29. 關鍵幀上的搜索建議
- 30. 獲取搜索查詢來自搜索框和谷歌SERP底部的建議
通過搜索建議你的意思是AutoCompleteTextView? – 2012-07-23 11:52:48
不,我正在使用Android搜索對話框。如文檔中所述:「使用Android搜索對話框或搜索小部件時,您可以提供自定義搜索建議,這些建議是根據應用程序中的數據創建的。」我想要做的是從服務器獲取這些建議,而不是從數據庫中獲得這些建議。 – toko 2012-07-24 05:10:47