Android的:如何从网络上获得的搜索建议异步?(Android: How to get sear

2019-07-30 13:50发布

我创建了一个可搜索的活动。 现在,我想补充一点,从网络服务采取的搜索建议。 我想这些建议是异步的。 据添加自定义的建议我需要重写的查询方法,做我的建议的搜索,建立自己的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没有发挥出来。 相反,我已经实现了其他两种解决方案:

  1. 在ArrayAdapter的自定义子类,本身使用过滤器的自定义子类组合使用AutoCompleteTextField。 该方法Filter#performFiltering()其余与向远程服务同步调用重写)异步调用和UI线程没有被阻塞。
  2. 使用带有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因为它是在显示功能这个答案 。



文章来源: Android: How to get search suggestions asynchronously from the web?