RxJava

RxJava防抖

2020-02-08  本文已影响0人  nickieeee
应用场景

快速多次点击按钮,就会提交多次事件。

一次普通的点击事件

mBtnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //这里为了更好理解,计算累加的结果
                index++;
                System.out.println("未添加防抖结果: "+ index);
            }
        });

打印结果:

2020-02-08 21:59:35.337 6487-6487/com.nick.rxjavathrottle I/System.out: 未添加防抖结果: 1
2020-02-08 21:59:35.482 6487-6487/com.nick.rxjavathrottle I/System.out: 未添加防抖结果: 2
2020-02-08 21:59:35.618 6487-6487/com.nick.rxjavathrottle I/System.out: 未添加防抖结果: 3

使用RxJava防抖

添加依赖:

implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
 RxView.clicks(mBtnAdd)
                .throttleFirst(2, TimeUnit.SECONDS)
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) {
                        index++;
                        System.out.println("防抖结果: "+ index);
                    }
});

打印结果:

2020-02-08 21:57:15.925 6189-6189/com.nick.rxjavathrottle I/System.out: 防抖结果: 1

源码分析

clicks

创建一个在指定view上可以发出的被观察者对象,这个方法返回了一个ViewClickObservable的实例化对象。

/**
   * Create an observable which emits on {@code view} click events. The emitted value is
   * unspecified and should only be used as notification.
   * <p>
   * <em>Warning:</em> The created observable keeps a strong reference to {@code view}. Unsubscribe
   * to free this reference.
   * <p>
   * <em>Warning:</em> The created observable uses {@link View#setOnClickListener} to observe
   * clicks. Only one observable can be used for a view at a time.
   */
  @CheckResult @NonNull
  public static Observable<Object> clicks(@NonNull View view) {
    checkNotNull(view, "view == null");
    return new ViewClickObservable(view);
  }

ViewClickObservable类

  @Override protected void subscribeActual(Observer<? super Object> observer) {
    if (!checkMainThread(observer)) {
      return;
    }
    Listener listener = new Listener(view, observer);
    observer.onSubscribe(listener);
    view.setOnClickListener(listener);
  }

最终其实也是通过setOnClickListener来给view绑定点击事件,此处的view就是mBtnAdd。

throttleFirst
返回值为observate对象,该observate只发出源observatesource在sequential期间发出的第一项。简单来说就是比如我在2s内连续点击了3次,这里只会处理第一次的结果,后面两次会忽略掉。throttleFirst(long windowDuration, TimeUnit unit) 第一个参数为时长,第二个参数为单位。

 /**
     * Returns an Observable that emits only the first item emitted by the source ObservableSource during sequential
     * time windows of a specified duration.
     * <p>
     * This differs from {@link #throttleLast} in that this only tracks passage of time whereas
     * {@link #throttleLast} ticks at scheduled intervals.
     * <p>
     * <img width="640" height="305" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/throttleFirst.png" alt="">
     * <dl>
     *  <dt><b>Scheduler:</b></dt>
     *  <dd>{@code throttleFirst} operates by default on the {@code computation} {@link Scheduler}.</dd>
     * </dl>
     *
     * @param windowDuration
     *            time to wait before emitting another item after emitting the last item
     * @param unit
     *            the unit of time of {@code windowDuration}
     * @return an Observable that performs the throttle operation
     * @see <a href="http://reactivex.io/documentation/operators/sample.html">ReactiveX operators documentation: Sample</a>
     */
    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.COMPUTATION)
    public final Observable<T> throttleFirst(long windowDuration, TimeUnit unit) {
        return throttleFirst(windowDuration, unit, Schedulers.computation());
    }



Demo:RxJavaThrottle

上一篇下一篇

猜你喜欢

热点阅读