一、过滤操作符列表

用于过滤和选择Observable发射的数据序列

方法 含义
filter() 过滤数据
takeLast() 只发射最后的N项数据
last() 只发射最后的一项数据
lastOrDefault() 只发射最后的一项数据,如果Observable为空就发射默认值
takeLastBuffer() 将最后的N项数据当做单个数据发射
skip() 跳过开始的N项数据
skipLast() 跳过最后的N项数据
take() 只发射开始的N项数据
first() , takeFirst() 只发射第一项数据,或者满足某种条件的第一项数据
firstOrDefault() 只发射第一项数据,如果Observable为空就发射默认值
elementAt() 发射第N项数据
elementAtOrDefault() 发射第N项数据,如果Observable数据少于N项就发射默认值
sample() , throttleLast() 定期发射Observable最近的数据
throttleFirst() 定期发射Observable发射的第一项数据
throttleWithTimeout() , debounce() 只有在空闲了一段时间后才发射数据,通俗的说,就是如果一段时间没有操作,就执行一次操作
timeout() 如果在一个指定的时间段后还没发射数据,就发射一个异常
distinct() 过滤掉重复数据
distinctUntilChanged() 过滤掉连续重复的数据
ofType() 只发射指定类型的数据
ignoreElements() 丢弃所有的正常数据,只发射错误或完成通知

二、过滤操作符

2.1 debounce

被观察者连续发射的数据的时间间隔 如果在指定时间 就被过滤拦截。

看一个栗子:

    public void test(){Observable.create(new ObservableOnSubscribe<Integer>() {@Overridepublic 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>() {@Overridepublic void accept(Integer integer) throws Exception {Log.e(TAG, "accept: "+integer);}}, new Consumer<Throwable>() {@Overridepublic 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: 4
02-10 10:24:05.928 31354-8852/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 5
02-10 10:24:06.438 31354-8852/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 6
02-10 10:24:07.039 31354-8852/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 7
02-10 10:24:07.739 31354-8852/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 8
02-10 10:24:08.540 31354-8852/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 9
02-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>() {@Overridepublic 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>() {@Overridepublic boolean test(Integer integer) throws Exception {//返回真就是满足条件,不拦截; 返回假就是不满足条件,拦截掉,不然观察者接收到。//大于5的才满足条件,才不拦截return integer > 5;}}).subscribe(new Consumer<Integer>() {@Overridepublic void accept(Integer integer) throws Exception {Log.e(TAG, "accept: "+integer);}}, new Consumer<Throwable>() {@Overridepublic 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: 6
02-10 10:26:40.869 10474-11359/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 7
02-10 10:26:41.569 10474-11359/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 8
02-10 10:26:42.370 10474-11359/cn.com.minstone.rxjavalearn E/SearchActivity: accept: 9
02-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>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(Integer value) {Log.e(TAG,"收到数据"+value);}@Overridepublic void onError(Throwable e) {}@Overridepublic void onComplete() {}});}

调用上面的方法,输出的是:

02-20 09:05:51.688 28437-28437/? E/FilterActivity: 收到数据1
02-20 09:05:51.688 28437-28437/? E/FilterActivity: 收到数据2
02-20 09:05:51.688 28437-28437/? E/FilterActivity: 收到数据3
02-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() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {}@Overridepublic void afterTextChanged(final Editable s) {//交给RxJava去做if(disposable != null && !disposable.isDisposed()){disposable.dispose();}disposable = Observable.create(new ObservableOnSubscribe<String>() {@Overridepublic void subscribe(ObservableEmitter<String> e) throws Exception {e.onNext(s.toString());}}).debounce(400, TimeUnit.MILLISECONDS).subscribeOn(AndroidSchedulers.mainThread()).filter(new Predicate<String>() {@Overridepublic boolean test(String s) throws Exception {//返回是否满足条件,真为继续执行下去,假不满足条件就是拦截了return s.trim().length() > 0;}}).flatMap(new Function<String, ObservableSource<List<String>>>() {@Overridepublic 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>>() {@Overridepublic 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>>() {@Overridepublic ObservableSource<String> apply(@NonNull TextViewTextChangeEvent textViewTextChangeEvent) throws Exception {//把发射的数据源变为文本Stringreturn Observable.just(textViewTextChangeEvent.text().toString());}}).filter(new Predicate<String>() {@Overridepublic boolean test(@NonNull String s) throws Exception {//是否同意继续发射return s.length()>0;}}).subscribe(new Consumer<String>() {@Overridepublic 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>() {@Overridepublic void call(Void aVoid) {//onNext回调Log.e(TAG, "call: 点击了按钮");}});

[Android开发] RxJava2之路五 - 过滤操作符例子Demo相关推荐

  1. android开发学习之路——连连看之游戏逻辑(五)

    GameService组件则是整个游戏逻辑实现的核心,而且GameService是一个可以复用的业务逻辑类. (一)定义GameService组件接口 根据前面程序对GameService组件的依赖, ...

  2. android开发学习之路——连连看之加载图片(三)

    正如前面AbstractBoard类的代码中看到的,当程序需要创建N个Piece对象时,程序会直接调用ImageUtil的getPlayImages()方法去获取图片,该方法将会随机从res\ dra ...

  3. Android开发笔记(九十五)自定义Drawable

    Drawable Bitmap是Android对图像的定义描述,而Drawable则是对图像的展现描述,在View视图中显示图像都是通过Drawable来实现的.其中有关Bitmap的介绍参见< ...

  4. android开发用百度识别图片格式,Android开发学习之路-机器学习库(图像识别)、百度翻译...

    对于机器学习也不是了解的很深入,今天无意中在GitHub看到一个star的比较多的库,就用着试一试,效果也还行.比是可能比不上TensorFlow的,但是在Android上用起来比较简单,毕竟Tens ...

  5. 初学者必读Android开发入门之路

    初学者必读Android开发入门之路 [IT168评论]本人一直致力于嵌入式相关知识和技术在中国大陆地区的技术传播及嵌入式产品及移动设备的系统和应用程序开发,近两年主要专注于3G技术领域,重点是研究A ...

  6. 我的Android开发校招之路

    终于,我的秋招结束啦!从7月17日开始,到10月19日结束.三个月里,有汗水.有挫败.有喜悦.有成长.有蜕变.....谨以此帖,记录自己的研究生生涯及秋招之路,希望能对后面的其他同学有所帮助. (一) ...

  7. Android开发笔记(一百五十四)OpenGL的画笔工具GL10

    上一篇文章介绍了OpenGL绘制三维图形的流程,其实没有传说中的那么玄乎,只要放平常心把它当作一个普通控件就好了,接下来继续介绍OpenGL具体的绘图操作,这项工作得靠三维图形的画笔GL10来完成了. ...

  8. Android开发学习之路-环境搭建

    这里选择使用android studio 集成开发环境,因为as是google推出的单独针对android开发的环境,并且迭代周期很快,因此,肯定会替代eclipse成为andorid的开发环境.对于 ...

  9. Android开发笔记(一百五十九)Android7.0的分屏模式

    现在的手机屏幕越来越大,使得在屏幕上同时开多个窗口不再奢侈,因此Android从7.0开始顺势推出了分屏功能,也被称作多窗口模式.比如把竖长的手机屏幕分成上下两个窗口,一边在上面的窗口中观看电影,一边 ...

最新文章

  1. 谷歌地图的全球森林监察系统,揭秘中国雾霾的惊天秘密!
  2. 【bzoj1565】[NOI2009]植物大战僵尸 拓扑排序+最大权闭合图
  3. Java网络编程及安全
  4. 十代i7前端总线频率_Intel 10nm十代酷睿终极版发布:频率暴涨、苹果独享
  5. 13.Git分支-变基(rebase)、rebase VS merge
  6. Laravel源码解析之HTTP Kernel
  7. Android 学习 笔记_07. XML文件解析
  8. 安装linux版qq,安装二进制包编译器,安装mysql-5.6.11,删除已安装或安装失败的mysql-5.6.11,简单mysql练习题...
  9. Rust : WSL下编程
  10. 计算机毕业设计-ssm超市进销存管理系统(项目+类似文档)超市仓库管理系统javaweb-超市库存预警管理系统源码
  11. 【OSPF基础(链路状态路由协议、ospf基础术语、ospf协议报文类型、ospf三大表项、邻居和邻接关系、ospf网络类型、DR与BDR、ospf基本配置)】-20211210、13、14
  12. python二元一次方程组用鸡兔同笼的思路来写编程_二元一次方程组的应用一鸡兔同笼问题...
  13. 谈谈Google AdSense以外的国外优秀广告联盟
  14. android动态mac地址,Android 版本兼容 — Android 6.0 和 7.0后获取Mac地址
  15. 如何使用树莓派连接电脑无线网络热点并查看树莓派ip地址
  16. 错误计算机怎么打开,例举电脑无法开机出现a disk read error错误怎么办呢?
  17. 【新年返程离不开Python】最新12306抢票源程序Python版就此分享给大家啦!
  18. 技术人攻略访谈四十-刘睿民:数据库战国时代,我不跟你们玩政治!
  19. 机械转嵌入式开发需要学什么东西?嵌入式软件工程师学习路线
  20. android开机动画bootanimation 分析

热门文章

  1. 【数字图像处理】图像的几何变换之 图形平移与旋转
  2. linux系统的6000端口是什么,3种关闭linux系统端口方法
  3. 三角测量(Triangulation 三角化)与 SVD 求解
  4. 微信小程序开发 | 02 - 轮播图实现(swiper组件)
  5. 【java基础】int和tinyint的区别
  6. 盛铭轩电商:详情页优化
  7. Gitee码云 操作
  8. **2021,靠谱的网赚项目,遇上靠谱的你,谁说赚钱不轻松**
  9. windows 生成免费ssl证书 配置 https
  10. box filtering