一、过滤操作符列表

用于过滤和选择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. HTMl中内联边框是怎样实现连接的
  2. leetcode-合并两个有序链表
  3. 3 软件测试对象,查找条件对象By—Selenium自动化测试指南(3)
  4. Java内存使用情况查看工具
  5. 切换输入法快捷键_输入法失灵怎么办?该怎么恢复?
  6. (Origin教程)在图片和表格中插入Latex公式
  7. 衣服的尺寸S、M、L、XL、XXL分别表示的型号大小顺序是什么?
  8. UVA 177 PaperFolding 折纸痕 (分形,递归)
  9. 天霆:桌面虚拟化正处于导入期
  10. 计算机处理器怎么看 64,怎么查看电脑处理器是32还是64位
  11. 技师学院计算机老师,技师学院计算机工程系组织开展观摩课活动
  12. 《自然语言处理技术综述(第三版)》(1)----正则表达式
  13. 第五项修炼与架构师感想
  14. latex 公式换行_如何在微信公众号中!编辑出漂亮的数学公式?
  15. 英语中For和To的区别
  16. #{}和${}的使用
  17. 用Arduino改装小米沙漠赛车
  18. python中init函数详解_Python 中__init__函数以及参数self
  19. python怎么换背景颜色_用opencv给图片换背景色的示例代码
  20. Java多线程类FutureTask源码阅读以及浅析

热门文章

  1. linux ll命令是什么
  2. android usb 默认mtp,usb修改为默认MTP模式
  3. 【全国计算机等级考试二级教程——C语言程序设计(2021年版)编程题答案-第8章】
  4. h5活动是什么意思_h5是什么(H5和Html5是一个东西吗)
  5. iOS - Icon图标、启动图片、审核图片尺寸
  6. 完整的软件开发流程是怎样的?
  7. 央企招聘:中国航天科工集团2023校园招聘
  8. 工欲善其事,必先利其器之—使用ImageMagick处理图片
  9. 使用openssl生成https证书
  10. 降维的基本知识点总结