如何使用SearchView,Retrofit和RxJava(RxBindings)实现搜索功能? [英] How to implement search feature with SearchView, Retrofit and RxJava (RxBindings)?

查看:212
本文介绍了如何使用SearchView,Retrofit和RxJava(RxBindings)实现搜索功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户键入SearchView小部件时,应用程序应 API调用(在后台线程中)以从服务器获取搜索结果,并在RecyclerView中显示它们(在UI线程中 ).

When the user types into the SearchView widget, the app should make an API call (in background thread) to fetch search results from server, and display them (in UI thread) in RecyclerView.

我在片段中使用以下代码:

I use the following code in my fragment:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.my_fragment, menu);
    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();

    SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));

    RxSearchView.queryTextChanges(searchView)
                .debounce(400, TimeUnit.MILLISECONDS)
                .map(CharSequence::toString)
                .switchMap(query -> retrofitService.search(query))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<List<Item>>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(LOG_TAG, "Error", e);
                    }

                    @Override
                    public void onNext(List<Item> items) {
                        // adapter.addItems(...)
                    }
                });
}

但我有一个例外:

java.lang.IllegalStateException: Must be called from the main thread. Was: Thread[RxIoScheduler-2,5,main]
at com.jakewharton.rxbinding.internal.Preconditions.checkUiThread(Preconditions.java:35)
at com.jakewharton.rxbinding.support.v7.widget.SearchViewQueryTextChangesOnSubscribe.call(SearchViewQueryTextChangesOnSubscribe.java:18)
at com.jakewharton.rxbinding.support.v7.widget.SearchViewQueryTextChangesOnSubscribe.call(SearchViewQueryTextChangesOnSubscribe.java:10)
...

当我删除.subscribeOn(Schedulers.io())时,创建片段时会触发搜索API调用,并且在SearchView中没有键入任何查询,我会被暴露

When I remove .subscribeOn(Schedulers.io()), the search API call is fired when fragment is created and no query is typed in SearchView and I get exeption

retrofit2.adapter.rxjava.HttpException: HTTP 422 

然后,当我键入搜索查询时,不再调用retrofitService.search(query).

then, when I type my search query retrofitService.search(query) is no longer called.

推荐答案

请记住,您实际上可以在rx链中使用多个observeOn和多个subscribeOn运算符.

Remember that you can actually use multiple observeOn and multiple subscribeOn operators in your rx chain.

尝试一下:

RxSearchView.queryTextChanges(searchView)
            .debounce(400, TimeUnit.MILLISECONDS)
            .map(CharSequence::toString)
            .subscribeOn(AndroidSchedulers.mainThread())
            .observeOn(Schedulers.io())
            .switchMap(query -> retrofitService.search(query))
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<List<Item>>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {
                    Log.e(LOG_TAG, "Error", e);
                }

                @Override
                public void onNext(List<Item> items) {
                    // adapter.addItems(...)
                }
            });

这基本上将导致该线程的使用:

This will basically result in this Thread usage:

这篇关于如何使用SearchView,Retrofit和RxJava(RxBindings)实现搜索功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆