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();
            }
        });
上一篇 RxJava2学习之六:登录后再获取用户信息
下一篇 RxJava2学习之八:防止按钮重复(连续)点击
目录
文章列表
1 MongoDB排序
MongoDB排序
2
Kubernetes 1.15安装部署EFK日志收集系统
Kubernetes 1.15安装部署EFK日志收集系统
3
React Native学习之在React Native中使用Flexbox
React Native学习之在React Native中使用Flexbox
4
Flutter Widget之ListTile
Flutter Widget之ListTile
5
MySQL实现主从复制功能
MySQL实现主从复制功能
最新评论
一位WordPress评论者
一位WordPress评论者
2月12日
您好,这是一条评论。若需要审核、编辑或删除评论,请访问仪表盘的评论界面。评论者头像来自 Gravatar。