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最近发射的数据
其中:
- Debounce 解决TextWatcher监听的第一个问题;
- 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全栈技术分享
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论