开篇
这篇我们要弄清楚以下两个问题:
- 1、为什么要做防抖动点击?
 
做防抖动点击的目的很简单:我们需要追求更高更优质的用户体验。当我们无意间快速多次点击某一个Button跳转界面时会弹出N个相同的界面,这就很影响用户体验性,为此我们不得不限制快速多次点击同一个Button。
- 2、防抖动点击原理是什么?
 
在快速多次点击中,我们只取其中一次点击事件,忽略其余的点击事件。我们通常的做法就是在一定的时间间隔内只取其中一次点击事件。
弄清楚了上面两个问题,下面着手实现逻辑。
这里链接几篇别人写的防抖动点击的相关博文:
- Android 实现防抖动(防快速点击)的最优雅做法
 - Android防止按钮两次点击
 - Android 按键防止过快点击(防抖),在ButterKnife中的简单解决方案。
 - Android:防止过快点击造成多次事件
 
都写得非常不错,但是,要么就是复杂化,要么就是用起来不方便。为止我琢磨出来了一套自己写法,简单易懂,用起来灰常方便。
立即体验
扫描以下二维码下载体验App(从0.2.3版本开始,体验App内嵌版本更新检测功能):
JSCKit库传送门:https://github.com/JustinRoom/JSCKit
工具类源码
/**
 * 防抖动点击
 *
 * @author jiangshicheng
 */
public class AntiShakeUtils {
    private final static long INTERNAL_TIME = 1000;
    /**
     * Whether this click event is invalid.
     *
     * @param target target view
     * @return true, invalid click event.
     * @see #isInvalidClick(View, long)
     */
    public static boolean isInvalidClick(@NonNull View target) {
        return isInvalidClick(target, INTERNAL_TIME);
    }
    /**
     * Whether this click event is invalid.
     *
     * @param target       target view
     * @param internalTime the internal time. The unit is millisecond.
     * @return true, invalid click event.
     */
    public static boolean isInvalidClick(@NonNull View target, @IntRange(from = 0) long internalTime) {
        long curTimeStamp = System.currentTimeMillis();
        long lastClickTimeStamp = 0;
        Object o = target.getTag(R.id.last_click_time);
        if (o == null){
            target.setTag(R.id.last_click_time, curTimeStamp);
            return false;
        }
        lastClickTimeStamp = (Long) o;
        boolean isInvalid = curTimeStamp - lastClickTimeStamp < internalTime;
        if (!isInvalid)
            target.setTag(R.id.last_click_time, curTimeStamp);
        return isInvalid;
    }
}
资源目录values下新建资源文件:
ids.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="last_click_time" type="id"/>
    ...
</resources>
实现原理:给Button设置名为last_click_time的tag标签并存储上一次点击的时间戳,在一定的时间间隔内只取第一次点击事件。如此, Button会随着界面的销毁而被释放,因而它的名为last_click_time的tag标签存储所占用的内存也会被释放回收。
使用起来那就是更简单了
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (AntiShakeUtils.isInvalidClick(v))
                    return;
                // TODO: 2018/7/1  
            }
        });
你还可以自定义有效点击的时间间隔:
        if (AntiShakeUtils.isInvalidClick(v, 800))
           return;
用过之后,从此不罢手!
篇尾
QQ:1006368252。
成功的秘诀,在永不改变既定的目的。 —— 卢梭









网友评论
https://www.jianshu.com/p/7b354eb8d0d3