安卓按钮防抖动之终极解决方案

开发过程中,我们经常会用到OnClick点击事件,常用的写法可能是这样的:

btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //TODO
            }
        });

或者是这样的:

btn.setOnClickListener(this);

@Override
public void onClick(View v) {
   //TODO
}

正常情况下,这样的代码是没有什么问题的,但是大家都知道安卓碎片化严重,每个手机的性能也千差万别。想必大家都遇到过,在比较卡的手机上,快速点击按钮打开一个页面,结果发现这个页面被打开了两次...

一般这种情况下,我们会打开百度,看看万能的网友都是怎么处理这种问题的(当时我就是这么做的),搜索到的处理方式可能是这样的:

btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //TODO
                btn.setClickable(false);
                btn.setEnabled(false);
            }
        });

也可能是这样的:

public abstract class NoDoubleClickListener implements OnClickListener {

    public static final int MIN_CLICK_DELAY_TIME = 1000;
    private long lastClickTime = 0;

    @Override
    public void onClick(View v) {
        long currentTime = Calendar.getInstance().getTimeInMillis();
        if (currentTime - lastClickTime > MIN_CLICK_DELAY_TIME{
            lastClickTime = currentTime;
            onNoDoubleClick(v);
        } 
     }  
 
    public abstract void onNoDoubleClick(View v);
}

btn.setOnClickListener(new NoDoubleClickListener() {
            @Override
            public void onNoDoubleClick(View v) {
                 //TODO
            }
        }); 

还有的说用RxBinding,由于涉及到Rxjava相关的知识,篇幅原因,我这里就不过多描述,感兴趣的同学可以自行百度了解。

当然,上述几种方式均能达到防止按钮快速点击,但是其弊端也比较明显。先说第一种方式,这种方法虽然可以防止快速点击,但是其给体验上的影响还是非常大的,想想如果你这个按钮点击后会有网络请求,如果网络请求执行过程比较长的话,按钮一直无法被点击,会让用户以为出现了bug;方式二相比第一种方法,体验上倒是没什么问题,但是其弊端在于只能通过匿名内部类的方式注册点击事件,当出现一个界面按钮比较多,写起来代码就显得比较臃肿了。

说了这么多,是时候展示真正的技术了,不多BB,直接上代码。

首先我们定义一个点击事件接口

public interface OnLimitClickListener {

    /**
     * 按钮点击事件
     * @param view
     */
    void onClick(View view);

}

再定义一个抽象类对我们的点击事件做一层包装

public class OnLimitClickHelper implements View.OnClickListener {
    public static final int LIMIT_TIME = 300;
    private long lastClickTime = 0;
    private OnLimitClickListener onLimitClickListener = null;

    public OnLimitClickHelper(OnLimitClickListener onLimitClickListener){
        this.onLimitClickListener = onLimitClickListener;
    }

    @Override
    public void onClick(View v) {
        long curTime = Calendar.getInstance().getTimeInMillis();
        if (curTime - lastClickTime > LIMIT_TIME) {
            lastClickTime = curTime;
            if(onLimitClickListener != null){
                onLimitClickListener.onClick(v);
            }
        }
    }
}

ok,完工!

最后我们看看Activity的使用:

public abstract class MainActivity extends AppCompatActivity implements OnLimitClickListener {
    private Button btn = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn = findViewById(R.id.btn);
        btn.setOnClickListener(new OnLimitClickHelper(this));
    }

    @Override
    public void onClick(View v) {
        //TODO
    }
}

觉得写的不错的朋友,帮忙点下喜欢,你们的支持是我创作的动力!大家有什么问题也可以在下方评论,有时间我会一一解答,感谢!

你可能感兴趣的:(安卓按钮防抖动之终极解决方案)