android判断是否被点击方法,Android判断是否快速点击新思路

Android判断是否快速点击新思路

背景需求在用户提交表单内容,请求接口的通用场景下,增删改查 crud 操作是比较频繁出现的操作。

对于改查操作来讲,并不会引起数据上的问题,影响的最多是接口重复调用;但是对于增删操作来讲,很容易引起数据重复添加,删除异常等问题。

对用户来讲,网络延时或者不稳定造成请求接口时出现的App反应迟缓,下意识的会进行重复提交;或者用户不小心进行的重复点击;又或者测试App自动化测试工具导致的短时间内大量重复点击。

这些场景都应该在代码实现的时候应该考虑的。

1. “笨”方法实现说是笨方法,当然也是出现重复提交问题时候,想到的最有效的方法。

1.1 状态标记

对于每个点击按钮,初始状态 isPressed = FALSE 进行状态判定,点击一次记录状态 isPressed = TURE ,然后进行接口请求或者其它处理,接口请求完成之后初始化该按钮状态 isPressed = FALSE 。

1.2 状态标记高级版Android中怎样设置按钮不能点击?

其实,和上面的方法没什么区别,只不过借助了Button的属性设置来完成的。

Button.setEnabled(false);//设置这个属性

思路和1.1一致,生了一个局部变量,依然有效!

2. Clever方法实现

其实,对于重复点击这类问题,只需要一个状态标记就能够解决,但是我们的之前的方法只适用于单个Button按钮,对于多个按钮,如果我们这么去做,必然是大量的 Ctrl+C 和 Ctrl+V,想想都心累,更别说我还真的这么干过。

如果有一种一劳永逸的方法岂不是很好,对了,然后我们想到了封装,从Button组件内部去判断岂不是美妙,这样我们只需要替换xml中的Button就可以完美的解决大量的按钮点击事件。

既然,Button按钮的事件点击是通过

setOnClickListener(OnClickListenerlistener)

方法注册的,我们只需要在注册的时候,替换新的Listener,加上我们自定义事件判断就可以搞定。

比如:

publicclassOnNoRepeatButtonextendsButton

{

publicButtonEx(finalContextcontext)

{

super(context);

}

publicButtonEx(finalContextcontext,finalAttributeSetattrs)

{

super(context,attrs);

}

publicButtonEx(finalContextcontext,finalAttributeSetattrs,finalintdefStyleAttr)

{

super(context,attrs,defStyleAttr);

}

@Override

publicvoidsetOnClickListener(finalOnClickListenerlistener)

{

super.setOnClickListener(newOnNoRepeatClickListener(listener));

}

}

我们的OnNoRepeatClickListener:

/**

* 防止快速点击中多次触发事件的自定义OnClickListener

*/

publicclassOnNoRepeatClickListenerimplementsOnClickListener

{

privatefinalOnClickListenermListener;

privatelonglastClickTime=0;

publicOnNoRepeatClickListener(finalOnClickListenerlistener)

{

this.mListener=listener;

}

@Override

publicvoidonClick(finalViewv)

{

synchronized(this)

{

//判断当前点击时间与上一次点击时间的间隔

if(System.currentTimeMillis()-this.lastClickTime>1000)

{

if(this.mListener!=null)

this.mListener.onClick(v);

//处理完响应事件后记录时间确保下次响应

this.lastClickTime=System.currentTimeMillis();

}

}

}

}Note: 代码中的1000单位是ms,具体的时间需要根据需求来定义。

3. Smart方法实现Clever方法已经算是一个相对好的解决思路,但是如果我们的Textview ,ImageView , View等组件点击事件重复需要怎么解决呢?

也需要我们重写每一个的组件的

setOnClickListener(OnClickListenerlistener)

来实现。

那么,如果我们在重写了Activity/Fragment中重写

View.OnClickListener

方法,对点击事件时间进行判断,便可以减少对View组件的

setOnClickListener(OnClickListenerlistener)

方法的重写。

上代码:

interfaceIBaseViewextendsView.OnClickListener{

/**

* 初始化数据

*

* @param bundle 传递过来的bundle

*/

voidinitData(finalBundlebundle);

/**

* 绑定布局

*

* @return 布局Id

*/

intbindLayout();

/**

* 初始化view

*/

voidinitView(finalBundlesavedInstanceState,finalViewview);

/**

* 业务操作

*/

voiddoBusiness();

/**

* 视图点击事件

*

* @param view 视图

*/

voidonWidgetClick(finalViewview);

}

BaseActivity.java

/**

*

 
 

* desc : Activity基类

*

*/

publicabstractclassBaseActivityextendsAppCompatActivityimplementsIBaseView{

/**

* 当前Activity渲染的视图View

*/

protectedViewcontentView;

/**

* 上次点击时间

*/

privatelonglastClick=0;

protectedBaseActivitymActivity;

@OverrideprotectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

mActivity=this;

Bundlebundle=getIntent().getExtras();

initData(bundle);

setBaseView(bindLayout());

initView(savedInstanceState,contentView);

doBusiness();

}

protectedvoidsetBaseView(@LayoutResintlayoutId){

setContentView(contentView=LayoutInflater.from(this).inflate(layoutId,null));

}

/**

* 判断是否快速点击

*

* @return {@code true}: 是
{@code false}: 否

*/

privatebooleanisFastClick(){

longnow=System.currentTimeMillis();

if(now-lastClick>=800){

lastClick=now;

returnfalse;

}

returntrue;

}

@OverridepublicvoidonClick(finalViewview){

if(!isFastClick())onWidgetClick(view);

}

}

总结

当然,Smart方法也不是最佳的解决方案,这样来做需要组件采用

setOnClickListener(this)

调用方式,让Activity/Fragment统一处理点击事件的响应,Clever和Smart的结合也是一个不错的选择。

Havefun,enjoyCoding...

来源: https://juejin.im/post/5a02a76f51882529bb456240

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值