很多電商類,閱讀類,視頻的app,都有搜索功能。接下來,我們使用Rxjava來優(yōu)化一下 搜索功能。
我記得以前我做的搜索功能是通過對(duì)EditText的addTextChangedListener進(jìn)行監(jiān)聽:
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();//網(wǎng)絡(luò)請(qǐng)求
}
});
但是,這樣做會(huì)不會(huì)有好下場(chǎng)的:
a.可能會(huì)導(dǎo)致很多沒有意義的請(qǐng)求,耗費(fèi)用戶的流量,因?yàn)闆]更改一次就會(huì)訪問網(wǎng)絡(luò),而且只是最后輸入的關(guān)鍵字是有用的,希望程序猿可以在開發(fā)中多多考慮一下流量的優(yōu)化問題。
b.可能導(dǎo)致用戶最終搜素的結(jié)果不是用戶想要的
例如:用戶開始輸入“AB”這個(gè)時(shí)候出現(xiàn)了兩個(gè)請(qǐng)求,一個(gè)是A關(guān)鍵字,一個(gè)是AB關(guān)鍵字。如果因?yàn)橐恍┰颍?AB"先返回?cái)?shù)據(jù),之后“A”在返回,這樣,A的結(jié)果就是覆蓋AB的請(qǐng)求結(jié)果,從而導(dǎo)致搜索結(jié)果不正確。
So,我們接下來介紹一下Rxjava優(yōu)化一下搜索
用到的操作符如下
1.debounce

debounce:發(fā)射數(shù)據(jù)時(shí),如果兩次數(shù)據(jù)的發(fā)射間隔小于指定時(shí)間,就會(huì)丟棄前一次的數(shù)據(jù),直到指定時(shí)間內(nèi)都沒有新數(shù)據(jù)發(fā)射時(shí)才進(jìn)行發(fā)射
2.filter

filter: 過濾數(shù)據(jù)。內(nèi)部通過OnSubscribeFilter過濾數(shù)據(jù)??梢愿鶕?jù)布爾值進(jìn)行相應(yīng)的操作
說了這么多廢話,狗子上代碼
給大家推薦一下大神寫的RxBinding,現(xiàn)在已經(jīng)和RXjava2完美結(jié)合咯,略略略
RxTextView.textChanges(editText)
//200毫秒執(zhí)行一次網(wǎng)絡(luò)操作
.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 {
//網(wǎng)絡(luò)請(qǐng)求
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 {
//顯示結(jié)果
adapter.clear();
adapter.addAll(strings);
adapter.notifyDataSetChanged();
Log.e(TAG, strings + "!");
}
});
運(yùn)行結(jié)果:
