Android-如何优雅的处理重复点击

转自: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();

            }
        });

可以看到经过封装之后,使用起来还是很方便的,但是有几个缺点

  1. 侵入性过大-OnClickListener全部替换为子类IClickListener
  2. 不可逆-不能很方便的还原为OnClickListener,因为不是同个回调
  3. 如果是第三方控件则无法处理重复点击
  4. 只能写成内部类方式-由于单继承特性,我们只能内部类回调,代码不美观

优雅的处理方式

重复点击的问题其实是如何动态控制原有的点击事件是否产生,而不是在原有的点击事件上增强功能;结合设计模式可以知道,代理模式可以很好的处理这种问题,而不是继承.

代理

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值