android防重复点击

android防重复点击

简介

此方法侵入性小,使用方便,代码量少,基于AspectJ实现
先看使用方式

    @SingleClick(2000)
    @Override
    public void onClick(View view) {
    	super.onClick(view)
    }

使用只需要在点击事件上面添加SingleClick(防重复点击时间)注解就好,是不是非常方便!

代码实现

1.加入AspectJ插件
在你工程的build.gradle里面加入

dependencies {
		//noinspection GradleDependency
        classpath 'com.android.tools.build:gradle:3.0.1'
        classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.0'
}

在你的module的build.gradle加入

apply plugin: 'com.android.application'
apply plugin: 'android-aspectjx'
dependencies {
	implementation 'org.aspectj:aspectjrt:1.8.9'
}

2.单击事件代码
先定义一个注解SingleClick

/**
 * author:  zhouchaoxiang
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SingleClick {
    long value() default 500;//默认的点击间隔时间
}

编写判断单击逻辑代码

import android.view.View;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import java.lang.reflect.Method;

/**
 * author:  zhouchaoxiang
 */
@Aspect
public class SingleClickAspect {
	/**
     * 最近一次点击的时间
     */
    private static long mLastClickTime;
    /**
     * 最近一次点击的控件ID
     */
    private static int mLastClickViewId;
    
    @Pointcut("execution(@SingleClick 的全路径(如:@com.demo.www.demo.annotation.SingleClick * *(..)))")
    public void methodAnnotated() {}

    @Around("methodAnnotated()")
    public void aroundJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable {
        // 取出方法的参数
        View view = null;
        for (Object arg : joinPoint.getArgs()) {
            if (arg instanceof View) {
                view = (View) arg;
                break;
            }
        }
        if (view == null) {
            return;
        }
        // 取出方法的注解
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        if (!method.isAnnotationPresent(SingleClick.class)) {
            return;
        }
        SingleClick singleClick = method.getAnnotation(SingleClick.class);
        // 判断是否快速点击
        if (!isFastDoubleClick(view, singleClick.value())) {
            // 不是快速点击,执行原方法
            joinPoint.proceed();
        }
    }
    /**
     * 是否是快速点击
     * @param v  点击的控件
     * @param intervalMillis  时间间期(毫秒)
     * @return  true:是,false:不是
     */
    public boolean isFastDoubleClick(View v, long intervalMillis) {
        int viewId = v.getId();
        long time = System.currentTimeMillis();
        long timeInterval = Math.abs(time - mLastClickTime);
        if (timeInterval < intervalMillis && viewId == mLastClickViewId) {
            return true;
        } else {
            mLastClickTime = time;
            mLastClickViewId = viewId;
            return false;
        }
    }
}

到这里整个逻辑就完成了,赶紧试试吧

### Android按钮重复点击的最佳实践 为了止按钮在短时间内被多次点击,通常采用设置冷却时间的方式。当用户第一次点击按钮后,在一定时间内禁用该按钮,直到计时结束再重新启用。 #### 使用Handler实现抖动效果 通过`Handler`来延迟处理用户的点击请求是一个常见做法: ```java private static final long CLICK_DELAY_TIME = 1000L; private boolean isClickable = true; button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!isClickable) return; // 执行具体逻辑 doSomething(); isClickable = false; new Handler().postDelayed(() -> isClickable = true, CLICK_DELAY_TIME); } }); ``` 此方法简单易懂,适用于大多数场景下的单次点击控制[^1]。 #### 利用RxBinding库简化操作 对于更复杂的项目,推荐使用[RxBinding](https://github.com/JakeWharton/RxBinding),它能够更加优雅地解决这个问题: ```kotlin val clickEvents = RxView.clicks(button) .throttleFirst(2, TimeUnit.SECONDS) clickEvents.subscribe { _ -> // 处理点击事件 } ``` 这种方式不仅实现了抖功能,还支持链式编程风格,使得代码结构更为清晰简洁[^2]。 #### 自定义属性方式 还可以考虑自定义控件并添加专门用于控制连续点击间隔的属性。这样做的好处是可以将此类需求封装起来供其他地方复用: ```xml <com.example.CustomButton android:id="@+id/custom_button" app:minClickInterval="800"/> ``` 对应的Java/Kotlin类内部则负责监听点击动作以及判断两次点击之间的时间差是否满足设定条件[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值