您的位置:首页 > 编程语言 > Java开发

RxJava操作符 debounce 和 distinctUntilChanged

2016-05-23 15:28 483 查看
1 debounce操作符是用来防重复数据的或者(防抖动):

public final Observable<T> debounce(long timeout, TimeUnit unit) {
return debounce(timeout, unit, Schedulers.computation());
} 可以看出只需要传入防抖时间就可以了,比如debounce(200, TimeUnit.MILLISECONDS)就代表如果释放的数据间隔上一次释放数据在200毫秒内则丢弃这一次释放,即不会引发onnext的执行。

2 distinctUntilChanged操作符顾名思义,只有当我们观察的数据状态发生改变的时候才会释放数据,而对于状态的定义可以使用默认也可以自己定义,默认情况下就是对前后两次数据进行比较,如果key相等则此次不释放,如果不相等则释放:

U currentKey = previousKey;
U key = keySelector.call(t);
previousKey = key;

if (hasPrevious) {
if (!(currentKey == key || (key != null && key.equals(currentKey)))) {
child.onNext(t);
} else {
request(1);
}
} else {
hasPrevious = true;
child.onNext(t);
} 需要注意的是,它只会对前后两次释放的数据进行比较。

那么了解了上面两个操作符,就可以知道注册页面是很适合它们的场景,特别是当所有输入框输入的数据满足一定的条件时才会使提交按钮变亮,一旦不满足则会变暗。代码如下:

private void combineListener() {
subscription.add(Observable.combineLatest(phoneViewObservable, passwordViewObservable,
new Func2<Boolean, Boolean, Boolean>() {
@Override public Boolean call(Boolean phoneEnable, Boolean passwordEnable) {
return phoneEnable && passwordEnable;
}
}).distinctUntilChanged().subscribe(inputChangeSubscriber()));
}

private void bindListenerToPhoneChange() {
phoneViewObservable = RxTextView.textChangeEvents(phoneView)
.debounce(DEBOUNCE_MILLISECONDS, TimeUnit.MILLISECONDS)
.map(new Func1<TextViewTextChangeEvent, Boolean>() {
/**
* phone text validation
*/
@Override public Boolean call(TextViewTextChangeEvent textViewTextChangeEvent) {
return !TextUtils.isEmpty(textViewTextChangeEvent.text().toString());
}
})
.observeOn(AndroidSchedulers.mainThread());
}

private void bindListenerToPasswordChange() {
passwordViewObservable = RxTextView.textChangeEvents(passwordView)
.debounce(DEBOUNCE_MILLISECONDS, TimeUnit.MILLISECONDS)
.map(new Func1<TextViewTextChangeEvent, Boolean>() {
/**
* password text validation
*/
@Override public Boolean call(TextViewTextChangeEvent textViewTextChangeEvent) {
return !TextUtils.isEmpty(textViewTextChangeEvent.text().toString());
}
})
.observeOn(AndroidSchedulers.mainThread());
}

/**
* toggle target view when emitted
*/
private Observer<Boolean> inputChangeSubscriber() {
return new EndSubscriber<Boolean>() {
@Override public void onNext(Boolean enable) {
toggleSubmitBackground(enable);
}

@Override public void onEnd() {

}
};
}
debounce防止了快速输入,distinctUntilChanged用于防止重复执行得到相同结果。当然这里使用了rxbinding。如果有多个输入框,只需要在combinelatest里面加上就可以了,需要注意的是如果需要对输入结果和其他单一变量变化(比如是否同意注册协议变量)的混合验证时,可能会在变量变化时进行手动触发工作流,因为所有需要验证的流程都需要走distinctUntilChanged这个节点,如果不走这个节点那么当单一变量有变化就不会被记录为上一次释放数据,因而可能会把正确的数据校验释放丢弃掉。手动触发可以使用PublishSubject。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: