我們時(shí)常有會(huì)碰到這種情形:在一個(gè)EditText中匹层,并且針對(duì)該文本:當(dāng)我輸入時(shí),一個(gè)響應(yīng)將被自動(dòng)觸發(fā)蛾号,從而打印出我輸入的文本稠项,或者現(xiàn)在這樣的反應(yīng)被稱為一個(gè)API的調(diào)用。所以鲜结,如果我們輸入的每一個(gè)字符做出的這種反應(yīng)將是一種浪費(fèi)展运,因?yàn)槲覀冎幌胄枰雷詈笠粋€(gè)輸入活逆,這意味著在我停止打字的時(shí)候它應(yīng)該只觸發(fā)一個(gè)call!
傳統(tǒng)解決方法
我用一個(gè)定時(shí)器拗胜,并且安排它在afterTextChanged()方法延時(shí)1000毫秒后調(diào)用run()方法
//Java
Timer timer = new Timer();
final TextView textView = (TextView) findViewById(R.id.textView);
final EditText editText = (EditText) findViewById(R.id.editText);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(final CharSequence s, int start, int before,
int count) {
if (timer != null)
timer.cancel();
}
@Override
public void afterTextChanged(final Editable s) {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("Output : " + editText.getText());
}
});
}
}, 1000);
}
});
使用RxJava
1.創(chuàng)建一個(gè)observable
2.添加Debounce operator蔗候,1000毫秒(1秒)的延遲
3.訂閱它
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(final Subscriber<? super String> subscriber) {
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
}
@Override
public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
subscriber.onNext(s.toString());
}
@Override
public void afterTextChanged(final Editable s) {
}
});
}
})
.debounce(1000, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(final String s) {
textView.setText("Output : " + s);
}
});
更少的樣板——RxBindings!
我們可以使用RxBindings——這是RxJava結(jié)合了Android的UI組件的API。
RxTextView.afterTextChangeEvents(editText)
.debounce(1000,TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(tvChangeEvent -> {
textView.setText("Output : " + tvChangeEvent.view()
.getText());
});