AspectJ处理重复点击过快点击事件

在开发的过程中,我们常常会遇到这样的需求,当用户过快的点击按钮时,只响应一次点击事件。
通常的做法是用一个变量记录上次点击的时间,然后取当前的时间和上次的点击时间的差值,只有大于预定的时间才会响应。
以下是我的几种实现方法,包括两类,一类是普通的做法,另外一类是用AspectJ加入切面来实现,实现起来更加的优雅。

1.普通做法

1.1实现方式一

1.建立一个父类,在父类里面实现是否拦截点击事件的判断

public class BaseActivity extends AppCompatActivity {

	    private static long clickGapTime = 0;
	
	    public static final int CLICK_GAP_RESPONSE = 500;//500ms内不响应
	
	    protected boolean clickGapFilter(){
	        long currentTimeMillis = System.currentTimeMillis();
	        if(currentTimeMillis-clickGapTime< CLICK_GAP_RESPONSE){
	            return false;
	        }
	        clickGapTime = currentTimeMillis;
	        return true;
	    }
	}

2.继承这个父类,然后在点击事件里面判断是否满足条件,只有满足了clickGapFilter才能够继续执行

  btn = (Button)findViewById(R.id.btn);
  btn.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
          if(clickGapFilter()){
              //执行任务
              Toast.makeText(MainActivity.this,"点击事件",Toast.LENGTH_SHORT).show();
          }
      }
  });
1.2实现方式二

1.创建一个抽象类,实现View.OnClickListener的方法,有一个抽象方法gapClick,只有当点击间隔大于500ms的时候才会执行gapClick函数。

public abstract class ClickGapListener implements View.OnClickListener{

    private static long clickGapTime = 0;

    public static final int CLICK_GAP_RESPONSE = 500;//500ms内不响应

    @Override
    public void onClick(View view) {
        long currentTimeMillis = System.currentTimeMillis();
        if(currentTimeMillis-clickGapTime > CLICK_GAP_RESPONSE){
            clickGapTime = currentTimeMillis;
            gapClick();
        }
    }

    protected abstract void gapClick();
}

2.实现ClickGapListener

btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new ClickGapListener() {
    @Override
    protected void gapClick() {
        Toast.makeText(MainActivity.this,"点击事件",Toast.LENGTH_SHORT).show();
    }
});

2.用AspectJ实现

使用AspectJ能够更加优雅的实现这个需求,且代码的侵入性更低。

2.1引入AspectJ

1.在项目的build.gradle当中加入引用

classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.0'

在这里插入图片描述
2.在app的build.gradle当中加入plugin

apply plugin: 'android-aspectjx'

在这里插入图片描述

3.在app或者其他的模块当中加入依赖

implementation 'org.aspectj:aspectjrt:1.8.9'

在这里插入图片描述

2.2制作切面

1.增加ClickGap注解

@Retention(RetentionPolicy.CLASS)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface ClickGap {
}

2.编写切面处理类

@Aspect
public class AspectUtil {
    private static long clickGapTime = 0;

    public static final int CLICK_GAP_RESPONSE = 500;//500ms内不响应

    //判断是否应该执行,true执行,false不执行
    protected boolean clickGapFilter(){
        long currentTimeMillis = System.currentTimeMillis();
        if(currentTimeMillis-clickGapTime< CLICK_GAP_RESPONSE){
            return false;
        }
        clickGapTime = currentTimeMillis;
        return true;
    }

    @Around("execution(@ClickGap * *(..))")
    public void clickGap(ProceedingJoinPoint proceedingJoinPoint)throws Throwable {
        if(clickGapFilter() == true) {
            proceedingJoinPoint.proceed();
        }
    }
}

3.使用,直接在执行的点击函数上增加ClickGap注解即可

 btn = (Button)findViewById(R.id.btn);
 btn.setOnClickListener(new View.OnClickListener() {
     @Override
     @ClickGap
     public void onClick(View view) {
         Toast.makeText(MainActivity.this,"hello",Toast.LENGTH_SHORT).show();
     }
 });

3.总结

使用AspectJ处理这类事件可以使得代码逻辑很清晰,其他类似网络请求前判断是流量还是WiFi、日志打印前判断当前是release版本还是debug版本之类的需求都可以使用这种方法实现。
不过需要注意的是,在项目当中大量加入注解,会使得编译比较慢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值