RxJava2学习之七:关键词搜索

TextWatcher监听的弊端

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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监听的第二个问题。

代码实现

添加依赖

1
2
3
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实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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();
}
});

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :