基于RxJava框架实现获取验证码的辅助类

本文实例为大家分享了RxJava实现获取验证码辅助类的具体代码,供大家参考,具体内容如下

应用场景:

一般的项目中都有获取验证码这个功能,并且可能不止一个地方用到。其逻辑时通的:
…实时监控输入框中手机号或者邮箱的合法性
…合法时可点击获取验证码按钮
…点击按钮时调用接口去请求验证码,同时按钮变为不可点击,显示倒计时
…请求成功时执行正常逻辑,请求失败后倒计时取消,按钮状态恢复

设计思路

…整个功能涉及的对象:一个EditText用于输入账号信息,一个获取验证码的Button,一个Rxjava的管理器用于管理Rx事件的生命周期(不同的管理方案可自行配对)
…初始化监控EditText输入,初始化防抖按钮点击事件
…处理事件中的逻辑
…开发两个抽象方法,获取验证码的方法和验证规则方法

代码

package txcap.com.bigtime.utils;

import android.widget.Button;
import android.widget.EditText;

import com.jakewharton.rxbinding.view.RxView;
import com.jakewharton.rxbinding.widget.RxTextView;

import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action0;
import rx.functions.Action1;
import txcap.com.bigtime.Constant;
import txcap.com.bigtime.R;
import txcap.com.library.core.app.BaseApplication;
import txcap.com.library.core.rx.RxManager;
import txcap.com.library.utils.file.ResUtil;

/**
 * @author gaojigong
 * @version V1.0
 * @Description: 处理验证码的工具
 * @date 17/3/22
 */
public abstract class CheckCodeUtil {
  private RxManager mRxManager;
  private Button btnGetCheckCode;
  private EditText edtAccount;
  //验证码获取中,按钮始终是倒计时状态,不受输入框事件的影响
  protected boolean countDowning = false;
  //用于取消倒计时

  private Subscription intervalSub;
  public CheckCodeUtil(RxManager mRxManager, Button btnGetCheckCode, EditText edtAccount) {
    this.mRxManager = mRxManager;
    this.btnGetCheckCode = btnGetCheckCode;
    this.edtAccount = edtAccount;
    init();
  }

  private void init() {
    RxView.enabled(btnGetCheckCode).call(false);
    Observable<CharSequence> observableAccount = RxTextView.textChanges(edtAccount);
    //账号输入不合理不能点击获取验证码
    mRxManager.add(observableAccount
        .subscribeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<CharSequence>() {
          @Override
          public void call(CharSequence charSequence) {
            if(!countDowning){//这样能减少重复执行
              if (etCheck(charSequence.toString())) {
                RxView.enabled(btnGetCheckCode).call(true);
              } else {
                RxView.enabled(btnGetCheckCode).call(false);
              }
            }
          }
        }));
    //点击获取验证码
    mRxManager.add(
        RxView.clicks(btnGetCheckCode)
            .throttleFirst(Constant.CLICK_THROTTLE, TimeUnit.SECONDS)
            .subscribe(new Action1<Void>() {
              @Override
              public void call(Void aVoid) {
                getCheckCode();
              }
            })
    );
  }
  /**
   * 获取验证码
   */
  private void getCheckCode() {
    intervalSub = Observable.interval(0,1,TimeUnit.SECONDS, AndroidSchedulers.mainThread())
        .take(Constant.CHECK_CODE_SECOND)
        .doOnSubscribe(new Action0() {
          @Override
          public void call() {
            getCodeNumber();
            //按钮变为不可点击
            RxView.enabled(btnGetCheckCode).call(false);
            countDowning = true;
          }
        })
        .subscribe(new Subscriber<Long>() {
          @Override
          public void onCompleted() {
            countDowning = false;
            RxTextView.text(btnGetCheckCode).call(ResUtil.getResString(BaseApplication.getAppContext(),R.string.get_check_code));
            if(etCheck(edtAccount.getText().toString())){
              RxView.enabled(btnGetCheckCode).call(true);
            }
          }

          @Override
          public void onError(Throwable e) {
            countDowning = false;
            RxTextView.text(btnGetCheckCode).call(ResUtil.getResString(BaseApplication.getAppContext(),R.string.get_check_code));
            if(etCheck(edtAccount.getText().toString())){
              RxView.enabled(btnGetCheckCode).call(true);
            }
          }

          @Override
          public void onNext(Long aLong) {
            RxTextView.text(btnGetCheckCode).call((Constant.CHECK_CODE_SECOND - aLong)+"s");
          }
        });

    mRxManager.add(intervalSub);
  }

  /**
   * 获取验证码
   */
  public abstract void getCodeNumber();

  /**
   * 验证规则
   * @param str
   * @return
   */
  public abstract boolean etCheck(String str);

  public void getCodeError(){
    if(null != intervalSub){
      if(!intervalSub.isUnsubscribed()){
        intervalSub.unsubscribe();
        RxTextView.text(btnGetCheckCode).call(ResUtil.getResString(BaseApplication.getAppContext(),R.string.get_check_code));
        RxView.enabled(btnGetCheckCode).call(true);
        countDowning = false;
      }
    }
  }
}

使用实例

@BindView(R.id.edt_account)
EditText edtAccount;
@BindView(R.id.btn_get_check_code)
Button btnGetCheckCode;
private CheckCodeUtil checkCodeUtil;
checkCodeUtil = new CheckCodeUtil(mRxManager,btnGetCheckCode,edtAccount) {
  @Override
  public void getCodeNumber() {
    mPresenter.getCode(edtAccount.getText().toString());
  }

  @Override
  public boolean etCheck(String str) {
    return StrCheckUtil.checkedAccount(str);
  }
};
@Override
public void getCodeFailed(String message) {
  showToastLong("获取验证码失败:" + message);
  checkCodeUtil.getCodeError();
}

特点

…减少代码冗余
…方便需求维护

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • RXjava网络获取图片数据的方法

    本文实例为大家分享了RXjava网络获取图片数据的具体代码,供大家参考,具体内容如下 RXjava // An highlighted block image = findViewById(R.id.tu); Observable.create(new ObservableOnSubscribe<Bitmap>() { @Override public void subscribe(ObservableEmitter<Bitmap> e) throws Exception { e.

  • 基于RxJava框架实现获取验证码的辅助类

    本文实例为大家分享了RxJava实现获取验证码辅助类的具体代码,供大家参考,具体内容如下 应用场景: 一般的项目中都有获取验证码这个功能,并且可能不止一个地方用到.其逻辑时通的: -实时监控输入框中手机号或者邮箱的合法性 -合法时可点击获取验证码按钮 -点击按钮时调用接口去请求验证码,同时按钮变为不可点击,显示倒计时 -请求成功时执行正常逻辑,请求失败后倒计时取消,按钮状态恢复 设计思路 -整个功能涉及的对象:一个EditText用于输入账号信息,一个获取验证码的Button,一个Rxjava的

  • 基于Bootstrap框架菜鸟入门教程(推荐)

    Bootstrap菜鸟入门教程 Bootstrap简介 Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷. 一.栅格系统 栅格系统的工作原理: "行(row)"必须包含在 .container (固定宽度)或 .container-fluid (100% 宽度)中,以便为其赋予合适的排列(aligment)和内补(padding). 通过"行(ro

  • 基于PHP实现短信验证码接口(容联运通讯)

    自己也是刚刚研究,希望对也在研究的伙伴有帮助. 步骤: 1.登录荣联运通讯注册获取ACCOUNT SID.AUTH TOKEN.Rest URL(生产).AppID(默认): 2.注册测试用手机号码(先注册测试号码方可使用): 3.下载demo示例,并将代码放到项目中(最好单独建文件夹存储). 代码区: 一.新建test.app.php(测试用控制器) <?php /* * 短信接口测试 */ class TestApp extends ShoppingbaseApp{ public funct

  • PHP实现用户异地登录提醒功能的方法【基于thinkPHP框架】

    本文实例讲述了PHP实现用户异地登录提醒功能的方法.分享给大家供大家参考,具体如下: 对于安全性要求比较高的web网站,特别是后台管理,有时候需要甄别自己的账号是否被盗或者是否有另一个人此刻登陆了在进行后台操作,这些都会很不安全,为了避免两个人同时登录同时操作,可以强制下线一个账号. 通过IP判断当然是不行的,因为IP是随时会在某一个网段内变化的,但是有一个机制,恰巧可以解决这个,那就是session,只要使用同一个浏览器访问网站,浏览器不关闭每个来访者的session_id是不变的,这也正是解

  • 基于react框架使用的一些细节要点的思考

    这篇文章主要是写关于学习react中的一些自己的思考: 1.setState到底是同步的还是异步的? 2.如何在子组件中改变父组件的state 3.context的运用,避免"props传递地狱" 4.组件类里有私有变量a,它到底改放在this.a中还是this.state对象中(作为属性a)呢? 1.setState到底是同步的还是异步的? class MyComponent extends React.Component{ constructor(props) { super(pr

  • AngularJS 实现点击按钮获取验证码功能实例代码

    html :样式采用了sui框架的样式,请自行引入查看,AngularJS,自己引入, <div ng-controller="forGetPassword" ng-app="routingDemoApp"> <form novalidate name="forget"> <header class="bar bar-nav"> <a href="javascript:his

  • 基于thinkPHP框架实现留言板的方法

    本文实例讲述了基于thinkPHP框架实现留言板的方法.分享给大家供大家参考,具体如下: 奋斗了一天,终于THINKPHP小邓留言版的概念版出来了 其实真的THINKPHP开发速度很快,作为一个互联网上"搬砖"的,从事这种 纯码农的事也是无可厚非的. 代码就实现了如下功能 1.留言功能. 2.验证功能. 3.分页显示功能. 就是写了几行代码(PS:页面设计代码不算,就算控制器和模型的代码) 下面我公布一下控制的器的代码,关于THINKPHP的代码规则我就不阐述了,看thinkphp手册

  • Codeigniter框架实现获取分页数据和总条数的方法

    本文实例讲述了Codeigniter框架实现获取分页数据和总条数的方法.分享给大家供大家参考.具体实现方法如下: 一般在数据分页的时候需要获取当前页的数据和总条数,一般人是在model中封装两个函数分别获取当前页的数据和数据总条数,业务逻辑类似,感觉有点冗余,可以封装在一起 复制代码 代码如下: /** * 获取分页数据及总条数 * @param string @tablename 表名 * @param mixed $where 条件 * @param int $limit 每页条数 * @p

  • SpringMVC下获取验证码实例详解

    SpringMVC下获取验证码实例详解 前言: 1.用户一开始登录的时候, 不建议出现验证码, 这一点在很多网站上已经体现的很好了, 只有当用户连续输错三次或者以上才会要求用户输入验证码. 2.记录用户输错次数最好不要使用 session 来记录, 因为 session 是跟客户端浏览器会话有关的, 如果用重启浏览器或者换新的浏览器再来登录或者试错, 就是新的回话了, 原来记录的错误次数就失效了. 建议此处采用缓存机制来实现, 简单处理就是采用 Map<用户登录id, 错误次数> 来实现, 如

  • Android采取BroadcastReceiver方式自动获取验证码

    Android 自动获取验证码的两种方式分别是BroadcastReceiver及ContentObserver,两种方式都需要进行注册.取消注册两个步骤 记得添加权限,本文先介绍其中一种. <uses-permission android:name="android.permission.RECEIVE_SMS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORA

随机推荐