美文网首页Android学习
简单防止控件快速点击

简单防止控件快速点击

作者: 锋ivy | 来源:发表于2017-04-06 14:46 被阅读276次

    在使用App的时候,经常会出现这种情况,比如快速点击的时候打开了两个一模一样的页面,或者弹出多个弹出框,或者快速点击的时候,提交了两次数据(一般情况下还会加Loading,然后加上设置控件的enable来实现)。这个时候就需要做一些处理来防止快速点击。
    我看了网上的一些做法,我认为是比较麻烦或者不可取的。比如,

    1. Activity设置启动模式为singleTop
    2. 定义一个变量来记录上一次点击时间,然后根据这个变量来判断是否可以点击。

    第一种方法比较侵入,因为有的页面有自己的启动模式,而且该方法只能用在打开页面的这种情况,并不能本质解决防止快速点击的问题
    第二种方法可以实现,但是比较麻烦,因为这样的话,如果一个页面有很多控件的话,就会出现很多的变量。
    我这里对第二种方法进行改进,使其可以针对单控件或者多控件,在使用时也与OnClickListener基本无异,使用了抽象代替了接口而已。(如果非要在Activivty等界面实现OnClickListener的话,可以使用动态代理的方法进行实现,代码都不变,需要设置监听的时候由原OnClickListener实例变更为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;
        //是阻止一个控件快速点击(比如快速点击A),还是所有设置了该监听的控件都不能快速点击(比如不能同时点击A,B控件,包括快速点击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(),然后在点击的时候通过SparseLongArray和控件id来记录上一次点击的时间戳,然后再次点击的时候根据当前时间戳和上一次点击的时间戳进行比较,看是否小于最小点击时间,如果是的话则不执行点击回调,否则的话执行点击。这样的话便可以简单的防止快速点击。使用的时候只需要简单的new一个PreventRepeatOnClickListener 实例,然后为需要该特性的控件设置该监听,即可以实现防止快速点击同一控件的问题。

    相关文章

      网友评论

      • 淼_33:写的挺好的,还考虑了所有的控件的点击,我以前是指定时间内不能响应点击事件。
      • ditclear:使用AspectJ 才是最好的选择
        http://www.jianshu.com/p/ea45670a364f
        ditclear:@锋ivy 嗯,很厉害,文章写的也很好
        锋ivy:@ditclear 是的 的确aop才是最好的选择 本文只是提供一个思路
      • zouzhenglu:何必,,Rx自带反抖动
        锋ivy::smirk: 年轻人,这是给不用RX的人看的,而且和RX实现原理也不太一样,功能有有点区别

      本文标题:简单防止控件快速点击

      本文链接:https://www.haomeiwen.com/subject/rqntattx.html