天天看點

android 布局防抖動,安卓按鈕防抖動之終極解決方案

開發過程中,我們經常會用到OnClick點選事件,常用的寫法可能是這樣的:

btn.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

//TODO

}

});

或者是這樣的:

btn.setOnClickListener(this);

@Override

public void onClick(View v) {

//TODO

}

正常情況下,這樣的代碼是沒有什麼問題的,但是大家都知道安卓碎片化嚴重,每個手機的性能也千差萬别。想必大家都遇到過,在比較卡的手機上,快速點選按鈕打開一個頁面,結果發現這個頁面被打開了兩次...

一般這種情況下,我們會打開百度,看看萬能的網友都是怎麼處理這種問題的(當時我就是這麼做的😳),搜尋到的處理方式可能是這樣的:

btn.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

//TODO

btn.setClickable(false);

btn.setEnabled(false);

}

});

也可能是這樣的:

public abstract class NoDoubleClickListener implements OnClickListener {

public static final int MIN_CLICK_DELAY_TIME = 1000;

private long lastClickTime = 0;

@Override

public void onClick(View v) {

long currentTime = Calendar.getInstance().getTimeInMillis();

if (currentTime - lastClickTime > MIN_CLICK_DELAY_TIME{

lastClickTime = currentTime;

onNoDoubleClick(v);

}

}

public abstract void onNoDoubleClick(View v);

}

btn.setOnClickListener(new NoDoubleClickListener() {

@Override

public void onNoDoubleClick(View v) {

//TODO

}

});

還有的說用RxBinding,由于涉及到Rxjava相關的知識,篇幅原因,我這裡就不過多描述,感興趣的同學可以自行百度了解。

當然,上述幾種方式均能達到防止按鈕快速點選,但是其弊端也比較明顯。先說第一種方式,這種方法雖然可以防止快速點選,但是其給體驗上的影響還是非常大的,想想如果你這個按鈕點選後會有網絡請求,如果網絡請求執行過程比較長的話,按鈕一直無法被點選,會讓使用者以為出現了bug;方式二相比第一種方法,體驗上倒是沒什麼問題,但是其弊端在于隻能通過匿名内部類的方式注冊點選事件,當出現一個界面按鈕比較多,寫起來代碼就顯得比較臃腫了。

說了這麼多,是時候展示真正的技術了,不多BB,直接上代碼。

首先我們定義一個點選事件接口

public interface OnLimitClickListener {

void onClick(View view);

}

再定義一個抽象類對我們的點選事件做一層包裝

public class OnLimitClickHelper implements View.OnClickListener {

public static final int LIMIT_TIME = 300;

private long lastClickTime = 0;

private OnLimitClickListener onLimitClickListener = null;

public OnLimitClickHelper(OnLimitClickListener onLimitClickListener){

this.onLimitClickListener = onLimitClickListener;

}

@Override

public void onClick(View v) {

long curTime = Calendar.getInstance().getTimeInMillis();

if (curTime - lastClickTime > LIMIT_TIME) {

lastClickTime = curTime;

if(onLimitClickListener != null){

onLimitClickListener.onClick(v);

}

}

}

}

ok,完工!😂😂😂

最後我們看看Activity的使用:

public abstract class MainActivity extends AppCompatActivity implements OnLimitClickListener {

private Button btn = null;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btn = findViewById(R.id.btn);

btn.setOnClickListener(new OnLimitClickHelper(this));

}

@Override

public void onClick(View v) {

//TODO

}

}

覺得寫的不錯的朋友,幫忙點下喜歡,你們的支援是我創作的動力!大家有什麼問題也可以在下方評論,有時間我會一一解答,感謝!