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。
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。
相关文章推荐
- java中文乱码解决之道(4):java编码转换过程
- Java面向对象编程概述
- Spring使用Cache、整合Ehcache
- java中文乱码解决之道(3):编码详情:伟大的创想—Unicode编码
- 第一个Java应用
- java中文乱码解决之道(2):字符编码详解:基础知识 + ASCII + GB**
- java中文乱码解决之道(1):认识字符集
- Java 数字转换为汉语中人民币的大写
- java中文乱码解决之道(7):JSP页面编码过程
- 【Spring】【笔记】《Spring In Action》第3章 简化XML配置
- Spring Boot下配置MyBatis多数据源
- JAVA多线程(三)生产者消费者模式及实现方法
- mac jdk 1.6下载地址
- ArrayList源码分析(JDK1.8)
- Java导出jar包(并用bat命令执行)
- eclipse not found servlet.api
- Spring 父子容器
- Jeeplus智能快速开发平台首页、文档和下载 - spring MVC mybatis ssm 框架 - 开源中国社区
- Eclipse配置Git
- 第一个JNI程序(Visual Studio与Eclipse配合)