神兵利器--RxBinding,用的就是你

为什么要使用RxBinding,如下场景:

点击防抖

原始实现方式

 public class FastActionGuard {
    private static final long MIN_ACTION_INTERVAL_MS = 1000; // 1s
    private static long sLastActionTimeMillis;

    private FastActionGuard() {}

    public static boolean isActionTooFast() {
        long now = SystemClock.elapsedRealtime();
        if (now - sLastActionTimeMillis < MIN_ACTION_INTERVAL_MS) {
            return true;
        } else {
            sLastActionTimeMillis = now;
            return false;
        }
    }
}

使用用RxBinding

 RxView.clicks(shakeBtn)
                .throttleFirst(1, TimeUnit.SECONDS)
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1() {
                    @Override
                    public void call(Void aVoid) {
                        //// TODO: 2017/5/4
                        showToast("throttleFirst 1秒内只响应第一次点击");
                    }
                });

监听某按钮多次点击,比如双击

原始使用方式

 public abstract class DoubleClick {
    
    protected Context mContext;
    
    /**
     * 开始任务的时间。
     */
    private long mStartTime;
    
    /**
     * 构造方法,初始化Context对象及开始的任务时间。
     * 
     * @param context
     */
    public DoubleClick(Context context) {
        mContext = context;
        mStartTime = -1;
    }
    
    /**
     * 当某个动作要双击才执行时,调用此方法。
     * 
     * @param delayTime
     *            判断双击的时间。
     * @param msg
     *            当第一次点击时,弹出的提示信息。如果为null,则不作提示。
     */
    public void doDoubleClick(int delayTime, String msg) {
        if (!doInDelayTime(delayTime)) {
            Toast.makeText(mContext, msg, delayTime).show();
        }
    }
    
    /**
     * 如果是在在指定的时间内则执行doOnDoubleClick,否则返回false。
     * 
     * @param delayTime
     *            指定的延迟时间。
     * @return 当且仅当执行了doOnDoubleClick时返回true,否则返回false。
     */
    protected boolean doInDelayTime(int delayTime) {
        long nowTime = DateUtil.getCurTime();
        if (nowTime - mStartTime <= delayTime) {
            afterDoubleClick();
            mStartTime = -1;
            return true;
        }
        mStartTime = nowTime;
        return false;
    }
    
    /**
     * 当某个动作要双击才执行时,调用此方法。
     * 
     * @param delayTime
     *            判断双击的时间。
     * @param msgResid
     *            当第一次点击时,弹出的提示信息的资源ID。
     */
    public void doDoubleClick(int delayTime, int msgResid) {
        if (!doInDelayTime(delayTime)) {
            Toast.makeText(mContext, msgResid, delayTime).show();
        }
    }
    
    /**
     * 在双击之后执行的事情。
     */
    abstract protected void afterDoubleClick();
}

使用用RxBinding

   Observable observable = RxView.clicks(doubleClickBtn).share();
        observable.buffer(observable.debounce(400, TimeUnit.MILLISECONDS))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1>() {
                    @Override
                    public void call(List voids) {
                        if (voids.size() >= 2) {
                            //double click detected
                            showToast(" 400毫秒内进行了" + voids.size() + "点次击");
                        }
                    }
                }, new Action1() {
                    @Override
                    public void call(Throwable throwable) {
                    

倒计时

原始实现方式

public class VerifyButton extends Button{
    private Context mContext;
    private Handler mHandler;
    private int mCount = 60;
    private OnVerifyBtnClick mOnVerifyBtnClick;

    public VerifyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setText("获取验证码");
        mContext = context;
        mHandler = new Handler();

    }


    public void requestSendVerifyNumber() {
        mHandler.postDelayed(countDown, 0);
        if (mOnVerifyBtnClick != null){
            mOnVerifyBtnClick.onClick();
        }

    }

    /**
     * The Count down of verification button
     */
    private Runnable countDown  = new Runnable() {
        @Override
        public void run() {
            VerifyButton.this.setText(mCount +"s ");
            VerifyButton.this.setBackgroundColor(getResources().getColor(R.color.disable_color));
            VerifyButton.this.setTextColor(getResources().getColor(R.color.common_gray));
            VerifyButton.this.setEnabled(false);

            if(mCount > 0) {
                mHandler.postDelayed(this, 1000);
            } else {
                resetCounter();
            }
            mCount -- ;
        }
    };

    public void removeRunable(){
        mHandler.removeCallbacks(countDown);
    }

    public void resetCounter(String... text) {
        this.setEnabled(true);
        if(null != text && text.length !=0 && !"".equals(text[0])){
            this.setText(text[0]);
        }else{
            this.setText("重获验证码");
        }
        this.setBackgroundColor(getResources().getColor(R.color.transparent));
        this.setTextColor(getResources().getColor(R.color.common_yellow));
        mCount = 60;
    }

    public interface OnVerifyBtnClick{
        void onClick();
    }

    public void setOnVerifyBtnClick(OnVerifyBtnClick onVerifyBtnClick) {
        this.mOnVerifyBtnClick = onVerifyBtnClick;
    }
}

使用用RxBindding

 timeObservable = RxView.clicks(timeBtn)
                .throttleFirst(1, TimeUnit.SECONDS)
                .subscribeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Action1() {
                    @Override
                    public void call(Void aVoid) {
                        RxView.enabled(timeBtn).call(false);
                    }
                });
        timeObservable.subscribe(new Action1() {
            @Override
            public void call(Void aVoid) {
                Observable.interval(0, 1, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
                        .take(SECOND + 1)
                        .subscribe(new Observer() {
                            @Override
                            public void onCompleted() {
                                RxTextView.text(timeBtn).call("点击倒计时");
                                RxView.enabled(timeBtn).call(true);
                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onNext(Long aLong) {
                                long curTime = SECOND - aLong;
                                RxTextView.text(timeBtn).call("倒计时 " + curTime + "s");
                            }
                        });
            }
        });

文字监听,view状态监听,登录:

原始实现方式

       //根据输入以及协议勾选框状态判断,是否需要高亮登录按钮
        usernameEt.addTextChangedListener(....);
        
        pwdEt.addTextChangedListener(....;
        
        protocolCb.setOnCheckedChangeListener(....);

使用用RxBinding

 Observable usernameOb = RxTextView.textChanges(usernameEt);
        Observable pwdOb = RxTextView.textChanges(pwdEt);
        Observable protocolOb = RxCompoundButton.checkedChanges(protocolCb);
        Observable.combineLatest(usernameOb, pwdOb, protocolOb, new Func3() {
            @Override
            public Boolean call(CharSequence username, CharSequence pwd, Boolean isChecked) {
                return !TextUtils.isEmpty(username) && !TextUtils.isEmpty(pwd) && isChecked;
            }
        }).subscribe(new Action1() {
            @Override
            public void call(Boolean aBoolean) {
                RxView.enabled(highLightkBtn).call(aBoolean);
            }
        });

搜索

原始实现方式

//不断监听当前输入框的文字变化,然后进行搜索,还需要自己判断用户是否输入完毕
searchEt(....);

使用用RxBinding

  RxTextView.textChanges(searchEt)
                  .debounce(500, TimeUnit.MILLISECONDS)
                  .observeOn(AndroidSchedulers.mainThread())
                  .map(new Func1() {
                      @Override
                      public String call(CharSequence charSequence) {
                          String searchKey = charSequence.toString();
                          if (TextUtils.isEmpty(searchKey)) {
                              showToast("搜索关键字不能为null");
                          }
                          else {
                              showToast("0.5秒内没有操作,关键字:" + searchKey);
                          }
                          return searchKey;
                      }
                  })
                  .observeOn(Schedulers.io())
                  .map(new Func1>() {
                      @Override
                      public List call(String searchKey) {
                          return search(searchKey);
                      }
                  })
                  .observeOn(AndroidSchedulers.mainThread())
                  .subscribe(new Action1>() {
                      @Override
                      public void call(List strings) {

                      }
                  });

权限管理

原始实现方式

if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
}else{
    //
}  

ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }
    }
}

使用用RxBinding

 final RxPermissions rxPermissions = new RxPermissions(this);
        RxView.clicks(rxPerimissionsBtn).
                throttleFirst(1, TimeUnit.SECONDS)
              .subscribeOn(AndroidSchedulers.mainThread())
              .compose(rxPermissions.ensure(Manifest.permission.CAMERA))
              .subscribe(new Action1() {
                  @Override
                  public void call(Boolean granted) {
                      if (granted) {
                          showToast("允许camera权限");
                      }
                      else {
                          showToast("拒绝camera权限");
                      }
                  }
              });

本文只写了我们常用的一些场景,后续继续补充

给我一个拒绝rxBinding的理由?

Demo:https://github.com/zhujian1989/mf

神兵利器--RxBinding,用的就是你_第1张图片
4.png

你可能感兴趣的:(神兵利器--RxBinding,用的就是你)