[Android开发] RxJava2之路五 - 过滤操作符例子Demo
来源:互联网 发布:淘宝卖家怎样包运费险 编辑:程序博客网 时间:2024/06/05 07:12
一、过滤操作符列表
用于过滤和选择Observable发射的数据序列
二、过滤操作符
2.1 debounce
被观察者连续发射的数据的时间间隔 如果在指定时间 就被过滤拦截。
看一个栗子:
public void test(){ Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) throws Exception { if(e.isDisposed()) return; try { //产生结果的间隔时间分别为100、200、300...1000毫秒 for (int i = 1; i <= 10; i++) { e.onNext(i); //发射数据 Thread.sleep(i * 100); } e.onComplete(); }catch(Exception ex){ e.onError(ex); } } }).subscribeOn(Schedulers.computation()) //被观察者在线程中执行 .debounce(400,TimeUnit.MILLISECONDS) //如果发射数据间隔少于400就过滤拦截掉 .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.e(TAG, "accept: "+integer); } }, new Consumer<Throwable>() { @Override public void accept(Throwable throwable) throws Exception { Log.e(TAG, "出错: "+throwable.toString()); } }); }
输出是这样的,400毫秒以前的就被过滤掉了:
02-10 10:24:05.527 31354-8852/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 402-10 10:24:05.928 31354-8852/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 502-10 10:24:06.438 31354-8852/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 602-10 10:24:07.039 31354-8852/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 702-10 10:24:07.739 31354-8852/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 802-10 10:24:08.540 31354-8852/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 902-10 10:24:09.441 31354-8852/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 10
2.2 filter
过滤数据,返回真就是满足条件,不拦截; 返回假就是不满足条件,拦截掉,不然观察者接收到。
这个可以对上面的编辑框输入搜索进一步优化,当内容为空的时候就过滤掉。
看一个栗子(上面的修改一下):
public void test(){ Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) throws Exception { if(e.isDisposed()) return; try { //产生结果的间隔时间分别为100、200、300...1000毫秒 for (int i = 1; i <= 10; i++) { e.onNext(i); Thread.sleep(i * 100); } e.onComplete(); }catch(Exception ex){ e.onError(ex); } } }).subscribeOn(Schedulers.computation()) .debounce(400,TimeUnit.MILLISECONDS) //如果发射数据间隔少于400就过滤拦截掉 .filter(new Predicate<Integer>() { @Override public boolean test(Integer integer) throws Exception { //返回真就是满足条件,不拦截; 返回假就是不满足条件,拦截掉,不然观察者接收到。 //大于5的才满足条件,才不拦截 return integer > 5; } }) .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.e(TAG, "accept: "+integer); } }, new Consumer<Throwable>() { @Override public void accept(Throwable throwable) throws Exception { Log.e(TAG, "出错: "+throwable.toString()); } }); }
对应输出的结果就是输出6以及6之后的数据:
02-10 10:26:40.268 10474-11359/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 602-10 10:26:40.869 10474-11359/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 702-10 10:26:41.569 10474-11359/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 802-10 10:26:42.370 10474-11359/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 902-10 10:26:43.271 10474-11359/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 10
2.3 take操作符
public void testLast(){ Observable.just(1, 2, 3, 4, 5, 6, 7, 8) .take(4) //发射前面四个数据 .subscribe(new Observer<Integer>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Integer value) { Log.e(TAG,"收到数据"+value); } @Override public void onError(Throwable e) { } @Override public void onComplete() { } }); }
调用上面的方法,输出的是:
02-20 09:05:51.688 28437-28437/? E/FilterActivity: 收到数据102-20 09:05:51.688 28437-28437/? E/FilterActivity: 收到数据202-20 09:05:51.688 28437-28437/? E/FilterActivity: 收到数据302-20 09:05:51.688 28437-28437/? E/FilterActivity: 收到数据4
其他的过滤操作符就自行测试了。
三、过滤的实际例子
3.1 搜索例子
比如在做搜索的时候,可以使用debounce减少频繁的网络请求。避免每输入(删除)一个字就做一次网络请求。
不使用Rxbinding的栗子:
etTest = (EditText) findViewById(R.id.et_test); etTest.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(final Editable s) { //交给RxJava去做 if(disposable != null && !disposable.isDisposed()){ disposable.dispose(); } disposable = Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> e) throws Exception { e.onNext(s.toString()); } }) .debounce(400, TimeUnit.MILLISECONDS) .subscribeOn(AndroidSchedulers.mainThread()) .filter(new Predicate<String>() { @Override public boolean test(String s) throws Exception { //返回是否满足条件,真为继续执行下去,假不满足条件就是拦截了 return s.trim().length() > 0; } }) .flatMap(new Function<String, ObservableSource<List<String>>>() { @Override public ObservableSource<List<String>> apply(String string) throws Exception { List<String> list = new ArrayList<String>(); for(Character charText:string.toCharArray()){ list.add(charText.toString()); } return Observable.just(list); } }) .observeOn(Schedulers.io()) .subscribe(new Consumer<List<String>>() { @Override public void accept(List<String> strings) throws Exception { Log.e(TAG, "accept: "+strings.size()); } }); } }); }
这样子当你不停在输入EditText的内容的时候,是不会打印的啦
使用了Rxbinding的栗子:
这里配合Rxbinding,利用这篇文章打包的rxbinding2all:http://blog.csdn.net/niubitianping/article/details/56014611
public void testDemo() { RxTextView.textChangeEvents(etTest) .debounce(300, TimeUnit.MILLISECONDS) //300毫秒内的连续编辑 过滤掉 .flatMap(new Function<TextViewTextChangeEvent, ObservableSource<String>>() { @Override public ObservableSource<String> apply(@NonNull TextViewTextChangeEvent textViewTextChangeEvent) throws Exception { //把发射的数据源变为文本String return Observable.just(textViewTextChangeEvent.text().toString()); } }) .filter(new Predicate<String>() { @Override public boolean test(@NonNull String s) throws Exception { //是否同意继续发射 return s.length()>0; } }) .subscribe(new Consumer<String>() { @Override public void accept(@NonNull String s) throws Exception { Log.e(TAG, "accept: "+s); } }); }
3.2 防止多次点击
点击一个按钮,取1秒内的第一次点击响应,防止多次点击。
Rxbinding例子:
这例子使用debounce也可以实现,但是实现的过成不一样,如果用的是debounce,必须得等待指定的事时间。如果用的是throttleFirst就是不用等待,执行第一个,指定时间的事件都过滤掉。这点要注意。
btTest = (Button) findViewById(R.id.bt_test);RxView.clicks(btTest) .throttleFirst(1, TimeUnit.SECONDS) //一秒内的点击只拿第一个,他的全过滤掉 .subscribe(new Action1<Void>() { @Override public void call(Void aVoid) { //onNext回调 Log.e(TAG, "call: 点击了按钮"); } });
2 0
- [Android开发] RxJava2之路五 - 过滤操作符例子Demo
- [Android开发] RxJava2之路十三-阻塞操作例子Demo
- [Android开发] RxJava2之路四 - 操作符简介与变换操作符例子Demo
- [Android开发] RxJava2之路十一- 算术和聚合操作符例子Demo
- [Android开发] RxJava2之路十二- 异步和连接操作符例子Demo
- [Android开发] Rxjava2之路: Rxbinding2(支持基于Rxjava2)
- [Android开发] RxJava2之路六
- [Android开发] RxJava2之路七
- [Android开发] RxJava2之路八
- [Android开发] RxJava2之路九
- [Android开发] RxJava2之路十
- RxJava2操作符之“Delay”
- [Android开发] RxJava2之路一 - 观察者模式
- [Android开发] RxJava2之路二 - 基本使用方法
- RxJava操作符之过滤操作符(五)
- RxJava2 / RxJava2操作符scan
- RxJava2.0之Android
- rxjava2操作符
- 节日短信中TabLayout+viewPager的简单使用
- iptables的规则说明和实践
- Docker热迁移研究背景,问题描述及解决方案
- 生物识别技术比较
- Python的切片原理
- [Android开发] RxJava2之路五 - 过滤操作符例子Demo
- 离开了公司,你还有什么
- 动规题集(更新)
- centos6.5网桥模式配置
- Python内存管理说明
- 深入理解java异常处理机制
- 如何在snap应用中为python项目定制自己的python版本
- Spring事务管理(二)
- 文字溢出时如何使溢出部分显示为 ...