1、功能防抖
- 用户在规定时间内触发多次该功能,仅会响应第一次该功能
- RxView.clicks源码分析
  eg:短时间内连续点击按钮
    public static void throttleFirst() {
        Button button = null;
        RxView.clicks(button)
                .throttleFirst(1, TimeUnit.SECONDS)
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        //跳转
                    }
                });
    }
 
 
2、联想搜索优化
![]()
    public static void search() {
        EditText editText = null;
        RxTextView.textChanges(editText)
                .debounce(1, TimeUnit.SECONDS)
                .skip(1)
                .subscribe(new Consumer<CharSequence>() {
                    @Override
                    public void accept(CharSequence charSequence) throws Exception {
                        //开始搜索
                    }
                });
    }
 
 
3、联合判断
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <EditText
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="请填写姓名"
        />
    <EditText
        android:id="@+id/age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="请填写年龄"
        />
    <EditText
        android:id="@+id/job"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="请填写职业"
        />
    <Button
        android:id="@+id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="提交"
        android:enabled="false"
        />
</LinearLayout>
 
        Observable<CharSequence> nameObservable = RxTextView.textChanges(name).skip(1);
        Observable<CharSequence> ageObservable = RxTextView.textChanges(age).skip(1);
        Observable<CharSequence> jobObservable = RxTextView.textChanges(job).skip(1);
        /*
         * 通过combineLatest()合并事件 & 联合判断
         **/
        Observable.combineLatest(nameObservable,ageObservable,jobObservable,new Function3<CharSequence, CharSequence, CharSequence,Boolean>() {
            @Override
            public Boolean apply(@NonNull CharSequence name, @NonNull CharSequence age, @NonNull CharSequence job) throws Exception {
          //1. 姓名
                boolean isUserNameValid = !TextUtils.isEmpty(name) 
                // 2. 年龄信息
                boolean isUserAgeValid = !TextUtils.isEmpty(age);
                // 3. 职业信息
                boolean isUserJobValid = !TextUtils.isEmpty(job) ;
                return isUserNameValid && isUserAgeValid && isUserJobValid;
            }
                }).subscribe(new Consumer<Boolean>() {
            @Override
            public void accept(Boolean s) throws Exception { 
                Log.e(TAG, "提交按钮是否可点击: " + s);
                list.setEnabled(s);
            }
        });
 
 
4、数据源合并
/ 用于存放最终展示的数据
        String result = "数据源来自 = " ;
        /*
         * 设置第1个Observable:通过网络获取数据
         * 此处仅作网络请求的模拟
         **/
        Observable<String> network = Observable.just("网络");
        /*
         * 设置第2个Observable:通过本地文件获取数据
         * 此处仅作本地文件请求的模拟
         **/
        Observable<String> file = Observable.just("本地文件");
        /*
         * 通过merge()合并事件 & 同时发送事件
         **/
        Observable.merge(network, file)
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }
                    @Override
                    public void onNext(String value) {
                        Log.d(TAG, "数据源有: "+ value  );
                        result += value + "+";
                    }
                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "对Error事件作出响应");
                    }
                    // 接收合并事件后,统一展示
                    @Override
                    public void onComplete() {
                        Log.d(TAG, "获取数据完成");
                        Log.d(TAG,  result  );
                    }
                });
 
 
5、网络/缓存策略
// 该2变量用于模拟内存缓存 & 磁盘缓存中的数据
        String memoryCache = null;
        String diskCache = "从磁盘缓存中获取数据";
        /*
         * 设置第1个Observable:检查内存缓存是否有该数据的缓存
         **/
        Observable<String> memory = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                // 先判断内存缓存有无数据
                if (memoryCache != null) {
                    // 若有该数据,则发送
                    emitter.onNext(memoryCache);
                } else {
                    // 若无该数据,则直接发送结束事件
                    emitter.onComplete();
                }
            }
        });
        /*
         * 设置第2个Observable:检查磁盘缓存是否有该数据的缓存
         **/
        Observable<String> disk = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                // 先判断磁盘缓存有无数据
                if (diskCache != null) {
                    // 若有该数据,则发送
                    emitter.onNext(diskCache);
                } else {
                    // 若无该数据,则直接发送结束事件
                    emitter.onComplete();
                }
            }
        });
        /*
         * 设置第3个Observable:通过网络获取数据
         **/
        Observable<String> network = Observable.just("从网络中获取数据");
        // 此处仅作网络请求的模拟
        /*
         * 通过concat() 和 firstElement()操作符实现缓存功能
         **/
        // 1. 通过concat()合并memory、disk、network 3个被观察者的事件(即检查内存缓存、磁盘缓存 & 发送网络请求)
        //    并将它们按顺序串联成队列
        Observable.concat(memory, disk, network)
                // 2. 通过firstElement(),从串联队列中取出并发送第1个有效事件(Next事件),即依次判断检查memory、disk、network
                .firstElement()
                // 即本例的逻辑为:
                // a. firstElement()取出第1个事件 = memory,即先判断内存缓存中有无数据缓存;由于memoryCache = null,即内存缓存中无数据,所以发送结束事件(视为无效事件)
                // b. firstElement()继续取出第2个事件 = disk,即判断磁盘缓存中有无数据缓存:由于diskCache ≠ null,即磁盘缓存中有数据,所以发送Next事件(有效事件)
                // c. 即firstElement()已发出第1个有效事件(disk事件),所以停止判断。
                // 3. 观察者订阅
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept( String s) throws Exception {
                        Log.d(TAG,"最终获取的数据来源 =  "+ s);
                    }
                });
 
 
6、轮询器
    Disposable mDisposable;
    //开启轮询
    public void autoLoop() {
        if (mDisposable == null || mDisposable.isDisposed()) {
            Observable.interval(0, 5, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.computation())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {
                        }
                    });
        }
    }
    //关闭轮询
    public void stopLoop() {
        if (mDisposable != null && !mDisposable.isDisposed()) {
            mDisposable.dispose();
            mDisposable = null;
        }
    }
 
 
7、定时器
   //一段时间之后再做一些事情
    public void timer() {
        Observable.timer(5, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        
                    }
                });
    }
 
 
8、倒计时
    public static void countDown(final int count) {
        Observable.intervalRange(0, count, 0, 1, TimeUnit.SECONDS)
                .map(new Function<Long, Long>() {
                    @Override
                    public Long apply(Long aLong) throws Exception {
                        return count - aLong;
                    }
                })
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe");
                    }
                    @Override
                    public void onNext(Long value) {
                        Log.d(TAG, "onNext: value = " + value);
                    }
                    @Override
                    public void onError(Throwable e) {
                    }
                    @Override
                    public void onComplete() {
                        Log.d(TAG, "onComplete");
                    }
                });
    }