观心静

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

前言

  按键防止连续点击是任何一个项目都要考虑的功能.下面我们将介绍几种防止按键连续点击的方法

 

用工具类实现

/**
 *@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);

 

posted on 2019-05-22 14:48  观心静  阅读(2894)  评论(0编辑  收藏  举报