前言
按键防止连续点击是任何一个项目都要考虑的功能.下面我们将介绍几种防止按键连续点击的方法
用工具类实现
/**
*@content:按键延时工具类,用于防止按键连点
*@time:2019-5-19
*@build:
*/
public class ButtonDelayUtil {
private static final int MIN_CLICK_DELAY_TIME = 1000;
private static long lastClickTime;
public static boolean isFastClick(){
boolean flag = false;
long curClickTime = System.currentTimeMillis();
if ((curClickTime - lastClickTime) >= MIN_CLICK_DELAY_TIME) {
flag = true;
}
lastClickTime = curClickTime;
return flag;
}
}
使用
mAdapter.setItemClickListener(new PTempEventListAdapter.OnItemClickListener() {
@Override
public void onItemClick(PTempEventListBase.TempEventData tempEventData) {
if (ButtonDelayUtil.isFastClick()){
Intent intent = new Intent(PTempEventListActivity.this, PTempEventDetailActivity.class);
intent.putExtra(PTempEventDetailActivity.APPLY_ID_KEY, tempEventData.getApplyId());
startActivity(intent);
}
}
});
很简单,但是使用的时候也很麻烦.也会让代码非常不简洁,可以作为一种补充办法.
在Kotlin里使用扩展函数的形式防止连续点击
private var clickInterval = 400L
private var lastTime = 0L
/**
* 延迟点击
*/
fun View.setOnIntervalClickListener(onIntervalClickListener: (View) -> Unit) {
this.setOnClickListener {
if (SystemClock.elapsedRealtime() - lastTime > clickInterval) {
lastTime = SystemClock.elapsedRealtime()
onIntervalClickListener.invoke(it)
}
}
}
重写点击OnClickListener类实现
public abstract class OnForbidClickListener implements View.OnClickListener {
private static final long DELAYED_TIME = 1000;
private long lastTime = 0;
public abstract void forbidClick(View view);
@Override
public void onClick(View v) {
if (System.currentTimeMillis()-lastTime > DELAYED_TIME){
lastTime = System.currentTimeMillis();
forbidClick(v);
}
}
}
使用
mFaceInfoText.setOnClickListener(new OnForbidClickListener() {
@Override
public void forbidClick(View view) {
Intent startFaceHome = new Intent(PParentInfoActivity.this, FaceHomeActivity.class);
startFaceHome.putExtra(FaceHomeActivity.FACE_USER_ID_KEY, mParentId);
startFaceHome.putExtra(FaceHomeActivity.FACE_IDENTITY_TYPE_KEY, 2);
startFaceHome.putExtra(FaceHomeActivity.FACE_SCHOOL_ID_KEY, PSPDataSession.I().getCurrentChildData().getSchoolId());
startActivity(startFaceHome);
}
});
其实跟上面的工具类是类似的,只不过将实现方式放入了重写的点击接口类里,也麻烦,但是至少会代码简洁一些
全局布尔值防止连续点击
其实上面的2个方式依然有可能被连点,比如点击后发送的是网络请求,请求完成后如果会finish Activity 就算你加了等待对话框,依然会有在等待对话框关闭 activity准备关闭的时候一直点击提交按钮的情况下触发第二次的网络请求.
所以下面方式就比较麻烦了,但是是能最好防止功能被连点的方式.所以一般是使用在网络请求上.
private boolean mPostAddApiing = false;
在请求接口的时候
mSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (TextUtils.isEmpty(mEditPhoneNumber.getText()) || mEditPhoneNumber.getText().toString().length() < 11) {
Toast.makeText(PParentAddActivity.this, "请输入正确的电话号码", Toast.LENGTH_SHORT).show();
return;
}
if (mEditVerificationCode.getText().toString().length() < 6) {
Toast.makeText(PParentAddActivity.this, "请输入正确的验证码", Toast.LENGTH_SHORT).show();
return;
}
if (!mPostAddApiing){
mPostAddApiing = true;
postAddApi();
}
}
});
然后在接口回调里如果是成功就不在处理mPostAddApiing 直接关闭finish activity,如果是activity不用关闭/提交失败/网络异常/用户主动取消请求的情况下,都要操作 mPostAddApiing = false, 让按键恢复可以点击;
当然也可以使用下面的方式一样可以达到效果,只要在对应想要开关的地方处理点击,但是这个逻辑上就比较隐式了
mSubmit.setClickable(false);