Android 防抖動多次點選問題處理及RxBinding事件流使用
前言
在日常開發工作中,會碰到Button按鈕點選處理使用者的需求,比如提交一個訂單到伺服器或跳轉進行支付按鈕操作,如果出現延遲情況造成介面短時間沒響應,使用者接下來就很有可能再去點選一次按鈕去提交,這樣就的話會造成上一個事件還未處理完又多了一個新的事件需要處理,就會出現提交兩次訂單到後臺伺服器或支付兩次。為了防止使用者抖動多次點選造成的問題,就要從點選事件本身去尋找解決辦法。
案件分析
一個普通的按鈕點選後跳轉到另一個頁面的程式碼片段,如下:
-
//按鈕點選事件:
-
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實現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();
-
}
-
});