很多電商類,閱讀類,視頻的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
debounce:發射數據時,如果兩次數據的發射間隔小于指定時間,就會丟棄前一次的數據,直到指定時間內都沒有新數據發射時才進行發射
2.filter
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 + "!");
}
});
運行結果:
不會動的,我不知道怎么讓他動