Android开发中很多场景都需要在短时间内避免重复点击一个按钮造成不必要的麻烦,就可以使用AOP的方式来实现这个功能。
一、使用AOP(面向切面编程,Android中是OOP面向对象编程)首先要在Studio中集成AOP。
集成AOP步骤:
1,在project的build文件中添加依赖: 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.10'。(gradle版 本大于4需要aspectjx2.0以上)
2,在app项目中(有‘com.android.application’的文件中)添加插 件
apply plugin: 'com.hujiang.android-aspectjx';
添加aspectjx {//排除所有package路径中包含`android.support`的class文件及库(jar 文件) exclude {'android.support','com.google'}
3,在需要使用的项目或库中添加 'org.aspectj:aspectjrt:1.8.+'。
验证是否集成成功:随便找一个类,在类名的上方使用注解@Aspect有效,就代表集成成功了。
二、新建一个类,类名随便
这个类文件保存在依赖module(没有就在主app module中)中任意package下就行了。不用任何配置或其他代码处理,代码中所有OnClickListener的地方就都会先判断是否是快速点击,然后再执行,达到防止重复点击的目标。
注意:上面有个 @RepeatClick注解的使用,如果有的场景不需要避免重复点击,就在onClick方法上加上这个注解。
``javascript
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.CONSTRUCTOR,ElementType.METHOD})
public @interface RepeatClick {
}
``
使用方法:这个onclik中的点击事件就不会有点击事件拦截了
终极优化方案:不是同一个View的点击,不进行点击过滤
```
//上次点击的时间
private static Long sLastclick =0L;
//拦截所有两次点击时间间隔小于一秒的点击事件
private static final Long FILTER_TIMEM =1000L;
//上次点击事件View
private View lastView;
//---- add content -----
//是否过滤点击 默认是
private boolean checkClick =true;
//---- add content -----
@Around("execution(* android.view.View.OnClickListener.onClick(..))")
public void onClickLitener(ProceedingJoinPoint proceedingJoinPoint)throws Throwable {
//大于指定时间
if (System.currentTimeMillis() -sLastclick >=FILTER_TIMEM) {
doClick(proceedingJoinPoint);
}else {
//---- update content ----- 判断是否需要过滤点击
//小于指定秒数 但是不是同一个view 可以点击 或者不过滤点击
if (!checkClick ||lastView ==null ||lastView != (proceedingJoinPoint).getArgs()[0]) {
//---- update content ----- 判断是否需要过滤点击
doClick(proceedingJoinPoint);
}else {
//大于指定秒数 且是同一个view
LogUtils.e(TAG,"重复点击,已过滤");
}
}
}
//执行原有的 onClick 方法
private void doClick(ProceedingJoinPoint joinPoint)throws Throwable {
//判断 view 是否存在
if (joinPoint.getArgs().length ==0) {
joinPoint.proceed();
return;
}
//记录点击的view
lastView = (View) (joinPoint).getArgs()[0];
//---- add content -----
//修改默认过滤点击
checkClick =true;
//---- add content -----
//记录点击事件
sLastclick =System.currentTimeMillis();
//执行点击事件
try {
joinPoint.proceed();
}catch (Throwable throwable) {
throwable.printStackTrace();
}
}
@Before("execution(@包名.RepeatClick * *(..))")
public void beforeEnableDoubleClcik(JoinPoint joinPoint)throws Throwable {
checkClick =false;
}
```