RxJava2学习之七:关键词搜索

TextWatcher监听的弊端

一般情况我们监听EditText控件,当值发生改变去请求搜索接口,如下:

EditText searchText = (EditText) this.findViewById(R.id.search_text);
searchText.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        //search(editable.toString().trim());  //请求搜索接口
    }
});

这里存在两个问题:

  • (1)可能导致很多没有意义的请求,耗费用户流量

因为控件的值每更改一次立即就会去请求网络,而且只是最后输入的关键字是有用的。

  • (2)可能导致最终搜索的结果不是用户想要的

例如,用户一开始输入关键字 ’AB’ 这个时候出现两个请求,一个请求是A关键字, 一个请求是AB关键字。表面上是’A’请求先发出去,‘AB’请求后发出去。如果后发出去的’AB’请求先返回,‘A’请求后返回,那么’A’请求后的结果将会覆盖’AB’请求的结果,从而导致搜索结果不正确。

RxJava实现

RxBinding

RxJava实现数据与视图的绑定使用到了RxBinding。

RxBinding是一个开源项目,可以实现数据层与View层的绑定,当数据发生变化,View会自动更新UI。

RxBinding:https://github.com/JakeWharton/RxBinding

注意:RxBinding目前只支持RxJava1

RxJava操作符

本例涉及的RxJava操作符:

  • Debounce只有在空闲一段时间后才发射数据,通俗的说,就是如果一段时间没有操作,就执行一次操作
  • Filter过滤,过滤掉没有通过谓词测试的数据项,只发射通过测试的
  • SwitchMap将一个发射Observable序列的Observable转换为这样一个Observable:它逐个发射那些Observable最近发射的数据

其中:

  1. Debounce 解决TextWatcher监听的第一个问题;
  2. SwitchMap 是有序的FlatMap,解决TextWatcher监听的第二个问题。

代码实现

添加依赖

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.jakewharton.rxbinding:rxbinding:1.0.0'

RxJava实现

EditText searchText = (EditText) this.findViewById(R.id.search_text);
//注意:RxBinding目前只支持RxJava1
RxTextView.textChanges(searchText)
        .debounce(500, TimeUnit.MILLISECONDS)
        .filter(new Func1<CharSequence, Boolean>() {
            @Override
            public Boolean call(CharSequence charSequence) {
                //过滤数据
                return charSequence.toString().trim().length() > 0;
            }
        })
        .subscribeOn(rx.android.schedulers.AndroidSchedulers.mainThread())
        .switchMap(new Func1<CharSequence, rx.Observable<List<String>>>() {
            @Override
            public rx.Observable<List<String>> call(CharSequence charSequence) {
                Log.i(TAG, "flatMap: " + charSequence);
                //模拟网络请求响应
                List<String> responses = new ArrayList<String>();
                responses.add("ok");
                responses.add("success");
                return rx.Observable.just(responses);
            }
        })
        /*
        .flatMap(new Func1<CharSequence, rx.Observable<List<String>>>() {
            @Override
            public rx.Observable<List<String>> call(CharSequence charSequence) {
                Log.i(TAG, "flatMap: " + charSequence);
                List<String> responses = new ArrayList<String>();
                responses.add("ok");
                responses.add("success");
                return rx.Observable.just(responses);
            }
        })
        */
        .subscribeOn(rx.schedulers.Schedulers.io())
        .observeOn(rx.android.schedulers.AndroidSchedulers.mainThread())
        .subscribe(new Action1<List<String>>() {
            @Override
            public void call(List<String> strings) {
                Log.i(TAG, "subscribe: " + strings);
            }
        }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                throwable.printStackTrace();
            }
        });

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/25/rxjava2-learning-7-keyword-search/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
RxJava2学习之七:关键词搜索
TextWatcher监听的弊端 一般情况我们监听EditText控件,当值发生改变去请求搜索接口,如下: EditText searchText = (EditText) this.findViewById(R.id.sear……
<<上一篇
下一篇>>
文章目录
关闭
目 录