安卓按钮防抖动之终极解决方案

开发过程中,我们经常会用到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 {

    /**
     * 按钮点击事件
     * @param view
     */
    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
    }
}

觉得写的不错的朋友,帮忙点下喜欢,你们的支持是我创作的动力!大家有什么问题也可以在下方评论,有时间我会一一解答,感谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 178,437评论 25 709
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 7,287评论 0 17
  • 文章转自:http://gank.io/post/560e15be2dca930e00da1083作者:扔物线在正...
    xpengb阅读 7,127评论 9 73
  • 本次课作业内容为: 选择自己的简书作业网址为目标分析页面 提交页面结构分析 提交元素标签位置信息 课业工具:chr...
    Bog5d阅读 396评论 0 1
  • 我的童年是在会宁南端的大山深处度过的,那里有我的故乡,有我的桑杏、玲檎、七月黄、艳果红和化心果,有我的地窝窝、麻雀...
    玮山阅读 1,547评论 4 1

友情链接更多精彩内容