github项目解析(七)-->防止按钮重复点击

转载请标明出处:一片枫叶的专栏

本文中我将介绍一下我自己封装的一个小的工具类库:按钮点击事件类库。

作用:

该类库可以防止按钮重复点击,可以判断网络状态,可以判断用户登录状态,以及自定义验证条件等等。

说明:

其实现的核心原理就是通过自定义实现自身的OnClickListener类,并重写其中的onClick方法,在onClick方法中执行相应的判断逻辑之后回调我们自定义的抽象方法。

具体效果如下图所示:

使用方式

  • 屏蔽多次点击事件
/**
  * 测试快速点击事件
  */
 fastButton.setOnClickListener(new OnClickFastListener() {
     /**
      * 自定义实现的抽象方法,不在重写onClick方法,该方法用于执行点击后的逻辑
      */
     @Override
     public void onFastClick(View v) {
         Toast.makeText(mContext, "您点击了测试网络按钮...", Toast.LENGTH_LONG).show();
     }
 });

这里的fastButton就是一个普通的按钮组件,然后我们为该组件设置了点击事件,并且传入的是我们自定义的OnClickListener类(这里需要说明的是,不只是button组件任何View组件的点击事件都是可以的,这里只是以Button组件为例子),这里默认的屏蔽多次点击事件的时间间隔为900ms,也就是说当我们为组件设置了我们自定义的点击事件监听之后,假如有两次点击事件,并且第二次点击时若距离第一次点击事件小于0.9s,则第二次点击不会起作用;

  • 屏蔽网络情况
/**
 * 测试网络状况
 */
networkButton.setOnClickListener(new OnClickNetworkListener() {
    /**
     * 自定义实现的抽象方法,主要用于执行有网络之后的逻辑
     */
    @Override
    public void onNetworkClick(View v) {
        Toast.makeText(mContext, "当前设备有网络,执行后续操作...", Toast.LENGTH_LONG).show();
    }

    /**
     * 自定义实现的抽象方法,主要用于执行当前设备没有网络之后的逻辑
     */
    @Override
    public void onNoNetworkClick(View v) {
        Toast.makeText(mContext, "当前设备没有网络...", Toast.LENGTH_LONG).show();
    }
});

同样的,这里的networkButton也是我们自定义的一个按钮组件,我们为其设置了点击事件监听,并传入了我们自定义的OnNetworkClickListener类,可以发现OnNetworkClickListener类中有两个回调方法,其中onNetworkClick方法用于执行当前设备有网的情况,而onNoNetworkClick方法用于处理当前设备没有网络的后续操作;

  • 屏蔽是否登录情况
/**
 * 测试是否登陆
 */
loginButton.setOnClickListener(new OnClickLoginedListener(mContext) {

    /**
     * 自定义实现的抽象方法,用于判断当前设备是否登录
     */
    @Override
    public boolean isLogined(Activity context, View view) {
        return false;
    }

    /**
     * 主要用于执行判断用户登录之后执行的逻辑
     */
    @Override
    public void onLoginedClick(View v) {
        Toast.makeText(mContext, "设备已登录,之后后续操作...", Toast.LENGTH_LONG).show();
    }

    /**
     * 主要用于执行判断用户未登录之后执行的逻辑
     */
    @Override
    public void onNoLoginedClick(View v) {
        Toast.makeText(mContext, "设备未登陆,无法执行后续操作...", Toast.LENGTH_LONG).show();
    }
});

这里的loginButton同样是我们自定义的一个按钮组件,并为其设置了我们的OnLoginedClickListener类,然后其中有三个回调方法,

其中方法isLogined用于判断当前用户是否登录,返回为true则表示用户已经登录,返回为false则表示用户未登录,具体实现逻辑需要在业务层实现,方法onLoginedClick用于执行登录之后的逻辑,而方法onNoLoginedClick用于执行用户尚未登录的逻辑。

这就是这个类库大概的实现功能,说完功能之后我们来看一下其具体实现逻辑:

实现方式

上面我们讲解了该类库的使用方式,那么我们是如何实现的呢?下面我们看一下该类库的源代码。

  • 防止按钮重复点击
/**
 * 方法按钮重复点击的监听类源码
 */
public abstract class OnClickFastListener extends BaseClickListener {

    // 防止快速点击默认等待时长为900ms
    private long DELAY_TIME = 900;
    private static long lastClickTime;

    private boolean isFastDoubleClick() {
        long time = System.currentTimeMillis();
        long timeD = time - lastClickTime;
        if (0 < timeD && timeD < DELAY_TIME) {
            return true;
        }
        lastClickTime = time;
        return false;
    }

    @Override
    public void onClick(View v) {
        // 判断当前点击事件与前一次点击事件时间间隔是否小于阙值
        if (isFastDoubleClick()) {
            return;
        }

        onFastClick(v);
    }

    /**
     * 设置默认快速点击事件时间间隔
     * @param delay_time
     * @return
     */
    public OnClickFastListener setLastClickTime(long delay_time) {

        this.DELAY_TIME = delay_time;

        return this;
    }

    /**
     * 快速点击事件回调方法
     * @param v
     */
    public abstract void onFastClick(View v);
}

以上就是我们防止按钮重复点击的OnFastClickListener的源码了,可以看到这里我们定义了防止重复点击的OnClickListener对象,并重写了其onClick方法,可以看到我们在onClick方法中调用了isFastDoubleClick方法,该方法就是具体实现是否重复点击逻辑的,当按钮上一次点击的时间与本次点击的时间间隔小于900ms的时候isFastDoubleClick方法就会返回为true,这时候onClick方法直接返回,不在执行后续的onFastClick方法,否则就直接执行onFastClick方法。然后我们在为我们的View组件设置点击事件的时候只需要重写onFastClick方法就好了。。。

  • 按钮点击监听网络状况
/**
 * 判断当前设备是否有网络的监听类源码
 */
public abstract class OnClickNetworkListener extends BaseClickListener {

    @Override
    public void onClick(View v) {
        boolean isNetworkOk = isNetworkConnected(v.getContext());

        if (isNetworkOk) {
            onNetworkClick(v);
        } else {
            onNoNetworkClick(v);
        }
    }

    // 点击事件--有网络
    public abstract void onNetworkClick(View v);

    // 点击事件--没有网络
    public abstract void onNoNetworkClick(View v);
    /**
     * 网络连接是否正常
     *
     * @param context
     * @return
     */
    public static boolean isNetworkConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
            if (mNetworkInfo != null) {
                return mNetworkInfo.isAvailable();
            }
        }
        return false;
    }
}

和刚刚的防止按钮重复点击事件类似,这里也是重写了自己的OnClickListener对象,然后重写了其onClick方法,并在其中执行isNetworkConnected方法,该方法就是判断是否当前设备是否有网络,若有网络则执行onNetworkClick方法,若无网络则执行onNoNetworkClick方法,这样当我们为自己的View组件设置点击事件的时候只需要为View组件设置onClickListener为我们自定义的OnClickListener对象,然后重写其中的onNetworkClick和onNoNetworkClick方法,其中onNetworkClick方法为有网络的回调方法,而onNoNetworkClick方法为无网络的回调方法。

  • 按钮点击监听是否登录
/**
 * 判断当前App用户是否登录的监听源码
 */
public abstract class OnClickLoginedListener extends BaseClickListener {

    private Activity context = null;

    public OnClickLoginedListener(Activity context) {
        this.context = context;
    }

    @Override
    public void onClick(View view) {
        super.onClick(view);

        if (isLogined(context, view)) {
            onLoginedClick(view);
        } else {
            onNoLoginedClick(view);
        }
    }

    /**
     * 判断当前用户是否登录
     * @param context
     * @param view
     * @return
     */
    public abstract boolean isLogined(Activity context, View view);

    /**
     * 用户登录之后执行的逻辑
     * @param v
     */
    public abstract void onLoginedClick(View v);

    /**
     * 用户未登录执行点击事件
     */
    public abstract void onNoLoginedClick(View v);
}

这里也是通过定义自身的OnClickListener类,然后重写其中的onClick方法,并在其中执行isLogined方法,该方法用于返回用户是否登录的逻辑判断,并且也是一个抽象的方法,所以也需要我们在业务层实现其具体的逻辑,然后我们重写了其中的onLoginedClick方法和onNoLoginedClick方法,其中onLoginedClick方法为用户登录之后的回调方法,而onNoLoginedClick方法为用户未登录之后执行的回调方法。

  • 定制化执行相应的业务逻辑
/**
 * 执行定制化判断逻辑的监听类源码
 */
public abstract class OnClickCostomListener extends BaseClickListener {

    @Override
    public void onClick(View view) {
        super.onClick(view);

        if (isCorrect()) {
            onCorrentClick(view);
        } else {
            onNoCorrentClick(view);
        }
    }

    /**
     * 判断是否逻辑通过
     * @return
     */
    public abstract boolean isCorrect();

    /**
     * 判断正确之后执行的逻辑请求
     * @param v
     */
    public abstract void onCorrentClick(View v);

    /**
     * 判断失败之后执行的逻辑请求
     * @param v
     */
    public abstract void onNoCorrentClick(View v);
}

可以看到这里重新定义了一个OnClickListener类,然后重写其中的onClick方法,首先执行判断方法isCorrect,然后若判断通过则执行onCorrentClick方法,若判断未通过则执行onNoCorrentClick方法。

这样我们就大概的分析了防止按钮重复点击类库的主要实现逻辑与功能,源码很简单,以后我会不断的开源与更新一些好用的类库的,希望大家多多支持。

总结:

  • 该类库主要是通过自定义OnClickListener类,并重写其中的onClick方法实现的;
  • 通过设置回调方法为抽象方法保证了我们必须要重写相应的回调方法;
  • 项目保存地址:android-repeatclick,欢迎star和follow

另外对github项目,开源项目解析感兴趣的同学可以参考我的:

github项目解析(一)–>上传android项目至github

github项目解析(二)–>将Android项目发布至JCenter代码库

github项目解析(三)–>android内存泄露监测之leakcanary

github项目解析(四)–>动态更改TextView的字体大小

github项目解析(五)–>android日志框架

github项目解析(六)–>自定义实现ButterKnife框架

时间: 2024-11-05 14:48:50

github项目解析(七)-->防止按钮重复点击的相关文章

Github项目解析(九)--&gt;实现Activity跳转动画的五种方式

转载请标明出处:一片枫叶的专栏 上一篇文章中我们讲解了在Activity启动过程中获取组件宽高的五种方式.在Activity的启动过程中如果我们直接在生命周期方法中通过view.getWidth()或者是view.getHeight()方法获取组件的宽度和高度其结果都是0,为什么会出现这个问题呢? 其实看过我以前写过的Activity启动流程  Activity布局加载流程  Activity布局绘制流程  的同学应该对Activity的启动流程和其布局加载绘制流程不陌生,Activity的启动

Github项目解析(十一)--&gt;一个简单,强大的自定义广告活动弹窗

转载请标明出处:一片枫叶的专栏 上一篇文章中讲解了我最近写的一个快速集成二维码扫描库,其核心的实现扫描的功能,是通过调用ZXing库实现的.由于在实现二维码扫描功能的时候发现集成二维码扫描功能并不是特别方便,于是有了将其制作成标准库的想法,这个二维码库能够快速,方便的集成二维码扫描功能,项目地址是在:android-zxingLibrary**,在项目开源后有不少同学提出了许多不错的意见,目前也在不断的迭代中,自己也学到了很多. 本文我们将讲解一个简单,强大的广告活动弹窗控件.不少App在打开的

github项目解析(八)--&gt;Activity启动过程中获取组件宽高的三种方式

转载请标明出处:一片枫叶的专栏 上一个github小项目中我们介绍了防止按钮重复点击的小框架,其实现的核心逻辑是重写OnClickListener的onClick方法,添加防止重复点击的逻辑,即为第二次点击与第一次点击的时间间隔添加阙值,若第二次点击的时间间隔与第一次点击的时间间隔小于阙值,则此次点击无效,再次基础上我们又封装了点击组件验证网络Listener,点击组件验证是否登录Listener等,具体可参考:github项目解析(七)–>防止按钮重复点击 本文中我将介绍一下android中A

github项目解析(六)--&gt;自定义实现ButterKnife框架

转载请标明出处:一片枫叶的专栏 目前在  友友用车  项目中使用到了ButterKnife框架,这是一个通过注解的方式简化程序员代码量,自动映射xml布局文件与对象关系的框架.其github上的地址  ButterKnife 这里简单介绍一下他的使用方式:android注解Butterknife的使用及代码分析 (一)使用方式 1)在activity中如何使用 @InjectView(R.id.feedback_content_edit) EditText feedContent; // 意见反

关于javascript中限定时间内防止按钮重复点击的思路

前面的话 有一天心血来潮,1分钟内重复点击了多次博客园首页的刷新博文列表的刷新按钮.果不其然,ip当时就被禁用了.后来,重启自己的路由器,重新获取ip才可以访问博客园主页.那么,设置一个限定时间内(比如1秒)防止按钮被重复点击的方法会不会更好一点呢? 思路一 最直接的思路可能就是点击按钮后,按钮的事件绑定函数解绑,1s后重新绑定函数 <button id="btn">0</button> <script> btn.onclick = function

按钮重复点击解决方案

防止重复提交,通用的思路,就是当用户点击提交按钮后,在浏览器中用JS将按钮disable掉,从而阻止用户继续点击该按钮,实现防止重复提交的目的.网上防止重复提交的文章已经不少了,为啥我还要写呢,显然我不是吃饱了撑的...最近一个客户,老抱怨每个月总有几条重复的业务数据:但创建该业务数据的页面,我们已经应用了常规的防重复提交技术,为啥还这样呢-- 1. 常规防重复提交 <asp:Button runat="server" ID="btnPostBack1" Te

React Native(十一)&mdash;&mdash;按钮重复点击事件的处理

最初开始做后台管理系统的时候,就曾遇到过这样一种场景:"快速点击确认按钮,就会对此触发确认事件,导致多次请求数据库":于是最终我们得当的通过处理那个确认button,解决了上述问题.而当自己开始使用RN做APP的时候,同样的问题居然也出现了,于是在处理完其他问题后,专门上网搜了一下此类问题的解决办法(不过好像都挺"高深一点",而自己却总认为越简单越好,那就摒弃了网上搜到的办法,另辟蹊径咯).突然意识到或许应该从源头解决,于是在官网中看到了这个: 原来在手机开发中也可

按钮重复点击问题 UIbutton

.h p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #c91b13 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo } p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; min-height: 21.0px } p.p4 { margin: 0.0px 0.0px 0

小程序 节流函数 (防止按钮重复点击)

function throttle(fn, gapTime) { if (gapTime == null || gapTime == undefined) { gapTime = 1500 } let _lastTime = null // 返回新的函数 return function () { let _nowTime = + new Date() if (_nowTime - _lastTime > gapTime || !_lastTime) { fn.apply(this, argume