很多电商类,阅读类,视频的app,都有搜索功能。接下来,我们使用Rxjava来优化一下 搜索功能。
我记得以前我做的搜索功能是通过对EditText的addTextChangedListener进行监听:
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
serarch();//网络请求
}
});
但是,这样做会不会有好下场的:
a.可能会导致很多没有意义的请求,耗费用户的流量,因为没更改一次就会访问网络,而且只是最后输入的关键字是有用的,希望程序猿可以在开发中多多考虑一下流量的优化问题。
b.可能导致用户最终搜素的结果不是用户想要的
例如:用户开始输入“AB”这个时候出现了两个请求,一个是A关键字,一个是AB关键字。如果因为一些原因,"AB"先返回数据,之后“A”在返回,这样,A的结果就是覆盖AB的请求结果,从而导致搜索结果不正确。
So,我们接下来介绍一下Rxjava优化一下搜索
用到的操作符如下
1.debounce
debounce:发射数据时,如果两次数据的发射间隔小于指定时间,就会丢弃前一次的数据,直到指定时间内都没有新数据发射时才进行发射
2.filter
filter: 过滤数据。内部通过OnSubscribeFilter过滤数据。可以根据布尔值进行相应的操作
说了这么多废话,狗子上代码
给大家推荐一下大神写的RxBinding,现在已经和RXjava2完美结合咯,略略略
RxTextView.textChanges(editText)
//200毫秒执行一次网络操作
.debounce(200, TimeUnit.MICROSECONDS)
.subscribeOn(AndroidSchedulers.mainThread())
//如果没有输入过滤一下
.filter(new Predicate<CharSequence>() {
@Override
public boolean test(CharSequence charSequence) throws Exception {
return charSequence.toString().trim().length() > 0;
}
})
.map(new Function<CharSequence, String>() {
@Override
public String apply(CharSequence charSequence) throws Exception {
String key = charSequence.toString();
return key;
}
})
.observeOn(Schedulers.io())
.map(new Function<String, List<String>>() {
@Override
public List<String> apply(String keyWord) throws Exception {
//网络请求
List<String> dataList = new ArrayList<String>();
if (!TextUtils.isEmpty(keyWord)) {
for (String s : getData()) {
if (s != null) {
if (s.contains(keyWord)) {
dataList.add(s);
}
}
}
}
return dataList;
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<String>>() {
@Override
public void accept(List<String> strings) throws Exception {
//显示结果
adapter.clear();
adapter.addAll(strings);
adapter.notifyDataSetChanged();
Log.e(TAG, strings + "!");
}
});
运行结果: