在使用App
的時候冈涧,經(jīng)常會出現(xiàn)這種情況,比如快速點(diǎn)擊的時候打開了兩個一模一樣的頁面,或者彈出多個彈出框蒂阱,或者快速點(diǎn)擊的時候录煤,提交了兩次數(shù)據(jù)(一般情況下還會加Loading
妈踊,然后加上設(shè)置控件的enable
來實(shí)現(xiàn))。這個時候就需要做一些處理來防止快速點(diǎn)擊歪泳。
我看了網(wǎng)上的一些做法露筒,我認(rèn)為是比較麻煩或者不可取的。比如慎式,
- 為
Activity
設(shè)置啟動模式為singleTop
- 定義一個變量來記錄上一次點(diǎn)擊時間,然后根據(jù)這個變量來判斷是否可以點(diǎn)擊鞍历。
第一種方法比較侵入肪虎,因?yàn)橛械捻撁嬗凶约旱膯幽J剑以摲椒ㄖ荒苡迷诖蜷_頁面的這種情況扇救,并不能本質(zhì)解決防止快速點(diǎn)擊的問題
第二種方法可以實(shí)現(xiàn)额获,但是比較麻煩,因?yàn)檫@樣的話,如果一個頁面有很多控件的話锌雀,就會出現(xiàn)很多的變量。
我這里對第二種方法進(jìn)行改進(jìn)婿牍,使其可以針對單控件或者多控件惩歉,在使用時也與OnClickListener
基本無異俏蛮,使用了抽象代替了接口而已上遥。(如果非要在Activivty
等界面實(shí)現(xiàn)OnClickListener
的話,可以使用動態(tài)代理的方法進(jìn)行實(shí)現(xiàn)粉楚,代碼都不變,需要設(shè)置監(jiān)聽的時候由原OnClickListener實(shí)例
變更為OnClickListener代理
)
import android.util.Log;
import android.util.SparseLongArray;
import android.view.View;
/**
* Created by ivy on 2017/4/5.
* Description:
*/
public abstract class PreventRepeatOnClickListener implements View.OnClickListener{
private SparseLongArray mLastClickTimeRecordArray=new SparseLongArray();
private long mClickInterVal=300;
//是阻止一個控件快速點(diǎn)擊(比如快速點(diǎn)擊A),還是所有設(shè)置了該監(jiān)聽的控件都不能快速點(diǎn)擊(比如不能同時點(diǎn)擊A,B控件包警,包括快速點(diǎn)擊A)
private boolean isPreventRepeatOnClickOneView=true;
private long mLastClickTime=0;
public void setClickInterVal(long clickInterVal){
this.mClickInterVal=clickInterVal;
}
public void setPreventRepeatOnClickOneView(boolean isPreventRepeatOnClickOneView){
this.isPreventRepeatOnClickOneView=isPreventRepeatOnClickOneView;
}
@Override
public void onClick(View v) {
if (v.getId()!=0){
if (isPreventRepeatOnClickOneView) {
preventOneViewRepeatClick(v);
}else{
preventAllViewRepeatClick(v);
}
}else{
Log.e(this.getClass().getName(),"this view("+v.toString()+") not set id, so we can't prevent repeat click!!");
}
}
private void preventAllViewRepeatClick(View v) {
long currentClickTime = System.currentTimeMillis();
if (currentClickTime-mLastClickTime>=mClickInterVal){
mLastClickTime=currentClickTime;
mLastClickTimeRecordArray.put(v.getId(),currentClickTime);
onClickView(v);
}
}
private void preventOneViewRepeatClick(View v) {
long lastClickTime = mLastClickTimeRecordArray.get(v.getId());
long currentClickTime = System.currentTimeMillis();
if (currentClickTime - lastClickTime >= mClickInterVal) {
mLastClickTime=currentClickTime;
mLastClickTimeRecordArray.put(v.getId(), currentClickTime);
onClickView(v);
}
}
abstract void onClickView(View v);
}
通過繼承OnClickListener()
害晦,然后在點(diǎn)擊的時候通過SparseLongArray
和控件id
來記錄上一次點(diǎn)擊的時間戳,然后再次點(diǎn)擊的時候根據(jù)當(dāng)前時間戳和上一次點(diǎn)擊的時間戳進(jìn)行比較鲫剿,看是否小于最小點(diǎn)擊時間稻轨,如果是的話則不執(zhí)行點(diǎn)擊回調(diào),否則的話執(zhí)行點(diǎn)擊殴俱。這樣的話便可以簡單的防止快速點(diǎn)擊。使用的時候只需要簡單的new
一個PreventRepeatOnClickListener
實(shí)例明场,然后為需要該特性的控件設(shè)置該監(jiān)聽李丰,即可以實(shí)現(xiàn)防止快速點(diǎn)擊同一控件的問題。