原文出自本人笔记:https://my.oschina.net/shawnxia/blog/632725
    现已迁移至此。


    最近接到一个重新定义耳机按键键功能的需求,其中Hook键集4个功能于一身,着实折腾了一番。

    最后在同事的提醒下,想到了采用handler的延时消息机制。思路如下:
    按钮点击,捕获事件,计数器+1,如果时间间隔大于延时时间,那么上一次的消息就已经触发了,上一次连击事件就判定结束了,此时将计数器置为0,重新开始计数;
    如果时间间隔小于延时时间,那么先将上一次发出的消息(此时还未被触发)remove掉,然后重新发送新的消息。大致流程如下:
    [M0]按键连续多次点击检测(原理) - 图1
    简单的实现过程如下:

    1. // 两次点击之间的最大时间间隔,也就是消息延迟的时间;
    2. // 一旦时间超过之后,上一次的消息就被触发了,那么连击也就结束了。
    3. private final static long DELAY_MILLIS = 1000;
    4. // 最多点击次数
    5. private final static int MAX_COUNTS = 3;
    6. // 用来发送延迟消息,每次发送之前,都要先将上一次消息remove掉,否则上一次消息仍旧会被触发。
    7. // 记录点击次数
    8. private int clickCounts = 0;
    9. // 处理连击事件
    10. private Runnable runnable = new Runnable() {
    11. @Override
    12. public void run() {
    13. textView.append("\nclickCounts = " + clickCounts);
    14. // 连击事件被消费之后,重置点击次数
    15. clickCounts = 0;
    16. // 还原按钮状态
    17. button.setText("Click me " + clickCounts);
    18. button.setClickable(true);
    19. }
    20. };
    21. public void btnClicked(View view) {
    22. // 点击次数大于最大次数,将按钮置为不可点击状态,
    23. // 避免出现按钮点击了,但次数没+1出现
    24. if(clickCounts >= MAX_COUNTS){
    25. button.setClickable(false);
    26. return;
    27. }
    28. // 点击次数+1
    29. clickCounts++;
    30. button.setText("Click me " + clickCounts);
    31. // 点击次数小于最大次数,remove上一次的消息(此时还未被触发),发送新的消息.
    32. // 如果两次事件间隔大于DELAY_MILLIS,那么上一次的消息就已经被触发了,
    33. // 此时再发出的消息会当作一次新的连击处理
    34. button.removeCallbacks(runnable);
    35. button.postDelayed(runnable, DELAY_MILLIS);
    36. }