Android开发——RXBinding防抖机制与案件分析
概述
在日常开发工作中,会碰到Button按钮点击处理用户的需求,比如提交一个订单到服务器或跳转进行支付按钮操作,如果出现延迟情况造成界面短时间没响应,用户接下来就很有可能再去点击一次按钮去提交,这样就的话会造成上一个事件还未处理完又多了一个新的事件需要处理,就会出现提交两次订单到后台服务器或支付两次。为了防止用户抖动多次点击造成的问题,就要从点击事件本身去寻找解决办法。
事件分析
为了避免例如用户对按钮多次点击,造成多次网络请求的现象。我们需要对按钮做防抖处理,即在指定时间内只响应一次点击事件。例如在短信验证登录时,多次点击就会发送多条短信,很影响体验,并且容易填错验证码。
这里选择使用的是RxBinding库,更简洁更容易理解,更适合我这样的新手。
首先我们需要导入依赖:
compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
activity中的实现代码:
RxView.clicks(button1)
.throttleFirst(3000,TimeUnit.MILLISECONDS)
subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
Log.i("RxView","点击了button1");
}
});
xml中的代码只有一个Button控件:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮1"
android:id="@+id/button1"/>
可以看到,无论我们怎么点击,都只会响应3秒内的第一次点击事件。
这里只展示了单个按钮,也可使用ButterKnife实现多个按钮防抖,相对简单这里就不展示了。
RXBinding防抖案件分析
一个普通的按钮点击后跳转到另一个页面的代码片段,如下:
//按钮点击事件:Button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //比如 跳转到另一个Activity } });
分析:
正常情况下会跳转到另一页面,如果碰到手机比较卡的情况,或者用户手抖瞬间点击两次,就会造成点击事件被调用两次,页面跳转了2次。作为程序员首先会想到的就是在点击之后把Button设置为不可点击或不可用 :“clickable=false | | Enable=false”;但是,类似这样的button一个项目不知道有多少个,每个都要进行判断是否是Button是否可用,就会比较麻烦、代码也显得冗余。有么有更好滴解决办法呢?
解决方案一
利用规定响应时间,限制连续点击事件重复。
private long lastClickTime = 0;//1、上次点击的时间 @Override public void onClick(View v) { //2、判断距离上次点击小于2秒 if (System.currentTimeMillis() - lastClickTime <= 2000) { //3、记录这次点击时间 lastClickTime = System.currentTimeMillis(); } }}其实这个解决方案就是判断了一下时间差,容易理解。但问题是,每次都要写(复制)一堆代码,显得代码冗余,重用性不高,如果能够封装成工具类的方法,在每次点击事件发生之前调用一下就可以自行内部判断,这样就更好了嘛!
方案二
随着Rxjava事件流处理、响应式开发的观察者模式兴起,那么对于Android控件事件监听也有了变化,通过 RxBinding 把点击的事件监听转换成 Observable 之后,就有了对它进行扩展的可能。
RxBinding的使用案例详解博文
RxBinding的使用和源码解析博文
这样可以使用RxBinding实现Button防抖问题处理。代码如下:(前后表示1.0\2.0版本用法有别)
button = (Button) findViewById( R.id.bt ) ;
RxView.clicks( button )
.throttleFirst( 2 , TimeUnit.SECONDS ) //两秒钟之内只取一个点击事件,防抖操作
.subscribe(new Action1<Void>() {
@Override
public void call(Void aVoid) {
Toast.makeText(MainActivity.this, "点击了", Toast.LENGTH_SHORT).show();
}
}) ;
RxView.clicks(button)
.throttleFirst( 2 , TimeUnit.SECONDS ) //两秒钟之内只取一个点击事件,防抖操作
.subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
Toast.makeText(MainActivity.this, "点击了", Toast.LENGTH_SHORT).show();
}
});
image
以上是对Android开发中的RXBinding防抖学习,以及实战的方案分析与解决。更多Android进阶技术《Android核心技术手册》点击直达参考学习更多的Android核心技术。
总结一下
- 响应式:就是有人发起,就有人响应,例如广播,发送请求后,广播拦截请求后就会做出相应。
- 事件流:一环一环先后顺序发生的事件。
- Rxjava的优点:使代码实现的结构看起来更清晰有条理章法。
- 观察者模式:就是教室里,老师是被观察者,学生就是观察者。老师说举手,学生受到指令就会做出响应。