转自:https://www.jianshu.com/p/d98e22c127ed?
问题
在客户端中,一些按钮一般是需要避免重复点击的,比如:购买丶支付丶确定丶提交丶点赞丶收藏等等场景,这些场景短时间内的重复点击会引发一些问题.
以前的处理方式
可能是采用手动记录最后的点击时间,再通过计算时间间隔来判断是否重复点击
long mLastClickTime = 0;
long TIME_INTERVAL = 1000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = findViewById(R.id.tv);
TextView tv2 = findViewById(R.id.tv2);
TextView tv3 = findViewById(R.id.tv3);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (System.currentTimeMillis() - mLastClickTime > TIME_INTERVAL) {
System.out.println("触发点击事件");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
startActivity(new Intent(MainActivity.this, SecondActivity.class));
mLastClickTime = System.currentTimeMillis();
} else {
Toast.makeText(MainActivity.this, "请勿重复点击", Toast.LENGTH_SHORT).show();
}
}
});
或者封装一下采用抽象处理
public abstract class IOnClickListener implements View.OnClickListener {
long mLastClickTime = 0;
long TIME_INTERVAL = 1000;
@Override
public void onClick(View v) {
if (System.currentTimeMillis()-mLastClickTime>TIME_INTERVAL){
onIClick(v);
mLastClickTime=System.currentTimeMillis();
}else {
onAgain(v);
}
}
protected abstract void onIClick(View view);
protected void onAgain(View v){
}
}
使用时:
tv2.setOnClickListener(new IOnClickListener() {
@Override
protected void onIClick(View view) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
startActivity(new Intent(MainActivity.this, SecondActivity.class));
}
@Override
protected void onAgain(View v) {
super.onAgain(v);
Toast.makeText(MainActivity.this, "请勿重复点击", Toast.LENGTH_SHORT).show();
}
});
可以看到经过封装之后,使用起来还是很方便的,但是有几个缺点
- 侵入性过大-OnClickListener全部替换为子类IClickListener
- 不可逆-不能很方便的还原为OnClickListener,因为不是同个回调
- 如果是第三方控件则无法处理重复点击
- 只能写成内部类方式-由于单继承特性,我们只能内部类回调,代码不美观
优雅的处理方式
重复点击的问题其实是如何动态控制原有的点击事件是否产生,而不是在原有的点击事件上增强功能;结合设计模式可以知道,代理模式可以很好的处理这种问题,而不是继承.
代理
public class ClickProxy implements View.OnClickListener {
long mLastClickTime = 0;
long timeInterval;
IAgain iAgain;
private View.OnClickListener onClickListener;
public ClickProxy(long timeInterval, View.OnClickListener onClickListener,IAgain iAgain) {
this.timeInterval = timeInterval;
this.onClickListener = onClickListener;
this.iAgain=iAgain;
}
@Override
public void onClick(View v) {
if (System.currentTimeMillis()-mLastClickTime>timeInterval){
onClickListener.onClick(v);
mLastClickTime=System.currentTimeMillis();
}else{
iAgain.onAgain();
}
}
public interface IAgain{
void onAgain();
}
}
使用时
tv3.setOnClickListener(new ClickProxy(1000, new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
startActivity(new Intent(MainActivity.this, SecondActivity.class));
}
}, new ClickProxy.IAgain() {
@Override
public void onAgain() {
Toast.makeText(MainActivity.this, "请勿重复点击", Toast.LENGTH_SHORT).show();
}
}));
代码
https://download.csdn.net/download/u013359807/10723122