開(kāi)發(fā)過(guò)程中,我們經(jīng)常會(huì)用到OnClick點(diǎn)擊事件,常用的寫(xiě)法可能是這樣的:
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//TODO
}
});
或者是這樣的:
btn.setOnClickListener(this);
@Override
public void onClick(View v) {
//TODO
}
正常情況下,這樣的代碼是沒(méi)有什么問(wèn)題的,但是大家都知道安卓碎片化嚴(yán)重,每個(gè)手機(jī)的性能也千差萬(wàn)別。想必大家都遇到過(guò),在比較卡的手機(jī)上,快速點(diǎn)擊按鈕打開(kāi)一個(gè)頁(yè)面,結(jié)果發(fā)現(xiàn)這個(gè)頁(yè)面被打開(kāi)了兩次...
一般這種情況下,我們會(huì)打開(kāi)百度,看看萬(wàn)能的網(wǎng)友都是怎么處理這種問(wèn)題的(當(dāng)時(shí)我就是這么做的??),搜索到的處理方式可能是這樣的:
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
}
});
還有的說(shuō)用RxBinding,由于涉及到Rxjava相關(guān)的知識(shí),篇幅原因,我這里就不過(guò)多描述,感興趣的同學(xué)可以自行百度了解。
當(dāng)然,上述幾種方式均能達(dá)到防止按鈕快速點(diǎn)擊,但是其弊端也比較明顯。先說(shuō)第一種方式,這種方法雖然可以防止快速點(diǎn)擊,但是其給體驗(yàn)上的影響還是非常大的,想想如果你這個(gè)按鈕點(diǎn)擊后會(huì)有網(wǎng)絡(luò)請(qǐng)求,如果網(wǎng)絡(luò)請(qǐng)求執(zhí)行過(guò)程比較長(zhǎng)的話(huà),按鈕一直無(wú)法被點(diǎn)擊,會(huì)讓用戶(hù)以為出現(xiàn)了bug;方式二相比第一種方法,體驗(yàn)上倒是沒(méi)什么問(wèn)題,但是其弊端在于只能通過(guò)匿名內(nèi)部類(lèi)的方式注冊(cè)點(diǎn)擊事件,當(dāng)出現(xiàn)一個(gè)界面按鈕比較多,寫(xiě)起來(lái)代碼就顯得比較臃腫了。
說(shuō)了這么多,是時(shí)候展示真正的技術(shù)了,不多BB,直接上代碼。
首先我們定義一個(gè)點(diǎn)擊事件接口
public interface OnLimitClickListener {
/**
* 按鈕點(diǎn)擊事件
* @param view
*/
void onClick(View view);
}
再定義一個(gè)抽象類(lèi)對(duì)我們的點(diǎn)擊事件做一層包裝
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
}
}
覺(jué)得寫(xiě)的不錯(cuò)的朋友,幫忙點(diǎn)下喜歡,你們的支持是我創(chuàng)作的動(dòng)力!大家有什么問(wèn)題也可以在下方評(píng)論,有時(shí)間我會(huì)一一解答,感謝!