Android 如何拦截用户频繁操作(点击事件)

目录
  • 前言
  • 解决方案
    • 场景1
    • 场景2
  • 总结

前言

在 Android 界面开发中,频繁操作是一个需要注意的点。 频繁操作: 频繁点击一个按钮,或者同时点击多个item,等产生的冲突情况。

解决方案

场景1

假设在 Activiyt A 界面有一个 按钮 T ,点击T 将跳转到 Activity B.

void handleClick(){
    Intent intent = new Intent(ActivityA.this,ActivityB.class);
    startActivity(intent);
}

但是用户很可能连续点击两下,那样 ActivityB就启动两个(在B是standard 启动模式),且用户若想回到ActivityA则需要点击返回键,这显然并不是一个特别好的体验。想必很多小伙伴都遇到过,解决方法自然就是通过 时间来判断,在一定时间内禁止操作。 不过总不能在每个方法里都写一遍 时间判断吧。如这样

long lastTime = 0;
void handleClick(){
    long currentTime = System.currentTimeMillis();
    if ( currentTime - lastTime < 200){
        return;
    }
    //具体操作
    ...
}

这种常用的方法,自然是要抽象一个类出来了。

public class OperateLock {
    private final static long DEFAULT_PERIOD = 200;
    private final long period;
    private long lastOperatorTime = 0;
    public OperateLock() {
        period = DEFAULT_PERIOD;
    }
    public OperateLock(int minimumPeriod) {
        period = minimumPeriod;
    }
    public boolean doing() {
        boolean doing = false;
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastOperatorTime > period) {
            lastOperatorTime = currentTime;
            doing = true;
        }
        return doing;
    }
    public boolean doing(int minimumPeriod) {
        boolean doing = false;
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastOperatorTime > minimumPeriod) {
            lastOperatorTime = currentTime;
            doing = true;
        }
        return doing;
    }
}

如上代码,就可以改成

private OperateLock operateLock = new OperateLock();
void handleClick(){
    if (!operateLock.doing()) return;
    //具体操作
    ...
}

不过以上代码在遇到很多个button的情况下,显然就要写很多个 operate 对象了,这显然也太多了,so,我们继续修改代码

public class ObjectOperateLock {
    private final static long DEFAULT_PERIOD = 200;
    private final long period;
    private long lastOperatorTime = 0;
    private List< WeakReference > operateObjList = new LinkedList<>();
    private HashMap< WeakReference, Long > timeHashMap = new HashMap<>();
    public ObjectOperateLock() {
        period = DEFAULT_PERIOD;
        Object obj = new Object();
    }
    public ObjectOperateLock(int minimumPeriod) {
        period = minimumPeriod;
    }
    public boolean doing(Object obj) {
        doing(obj, period);
    }
    public boolean doing(Object obj, long minimumPeriod) {
        boolean doing = false;
        long lastOperateTime = 0;
        WeakReference wk = null;
        Iterator< WeakReference > iterator = operateObjList.iterator();
        while (iterator.hasNext()) {
            WeakReference w = iterator.next();
            if (w.get() == null) {
                iterator.remove();
                timeHashMap.remove(w);
            } else if (w.get() == obj) {
                wk = w;
            }
        }
        if (wk == null) {
            wk = new WeakReference(obj);
            operateObjList.add(wk);
            timeHashMap.put(wk, 0L);
            doing = true;
        } else {
            long cur = System.currentTimeMillis();
            lastOperateTime = timeHashMap.get(wk);
            if (cur - lastOperateTime > minimumPeriod) {
                doing = true;
                lastOperateTime = cur;
                timeHashMap.put(wk, lastOperateTime);
            }
        }
        return doing;
    }
}

拦截频繁点击代码改为:

private ObjectOperateLock operateLock = new ObjectOperateLock();
void handleClickButton1(View v){
    if (!operateLock.doing(v)) return;
    //具体操作
    ...
}
void handleClickButton2(View v){
    if (!operateLock.doing(v)) return;
    //具体操作
    ...
}

当然,ObjectOperateLock 中所有方法也可以改为静态的,但是那样不利于设置一个默认的周期,比如 某几个 button可能是要 200毫秒以内只能点击一次,但是另一些View 则是500毫秒内只能点击一次。 那么既然使用了 ObjectOperateLock 是不是就不需要用 OperateLock了,当然不是 OperateLock 也有其用处。

场景2

有一个 RecyclerView ,其有一堆 item,item 点击后会跳进一个页面,item携带的数据是不同的,那如何拦截item的频繁点击呢。

相对于场景1,此种场景下,会出现一个问题,即,存在 两个 item同时被点击的情况。(两个手指同时点击不同的 item).这种情况,就可以用 OperateLock。

private OperateLock operateLock = new OperateLock();
void handleItemClick(View v){
    if (!operateLock.doing()) return;
}

总结

不仅仅是点击按钮事件,还有其他的频繁操作都需要设置一个规定时间不可重复操作,因此遇到这些拦截频繁操作的时候,就根据需要写一个拦截类吧。

到此这篇关于Android 如何拦截用户频繁操作(点击事件)的文章就介绍到这了,更多相关Android拦截用户频繁操作内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android模拟用户点击的实现方法

    前言 Android模拟用户点击.在自动化测试中可使用的工具. 可以利用adb命令,也可以使用Android SDK中的monkeyrunner工具. win7-64 gitbash 使用adb命令 主要使用input命令 usage: input ... input text <string> input keyevent <key code number or name> input tap <x> <y> input swipe <x1>

  • Android启动页用户相关政策弹框的实现代码

    现在Android上架各大平台都要求App首页添加一个弹框,显示用户协议以及一些隐私政策,不然上架各大平台,现在就来简单的实现一下这个对话框 既然是一个对话框,那我们就先来简单的封装一个对话框,这样方便后续的一些修改: widget_user_dialog.xml <?xml version="1.0" encoding="utf-8"?> <androidx.appcompat.widget.LinearLayoutCompat xmlns:an

  • android10 隐藏SystemUI锁屏下的多用户图标的示例代码

    需求:如上图,需要隐藏右上角的多用户蓝色图标. 修改后结果如下: 锁屏相关的布局在SystemUI frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java //更新多用户图标的可见性 private void updateVisibilities() { if (mMultiUserSwitch.getParent() != mStatusIconA

  • Android基于AlarmManager实现用户在线心跳功能示例

    本文实例讲述了Android基于AlarmManager实现用户在线心跳功能.分享给大家供大家参考,具体如下: 在做即时通信或者其他检测是否在线等操作时要用到心跳.比较常用的是AlarmManager全局定时器 去实现. AlarmManager的使用机制有的称呼为全局定时器,有的称呼为闹钟.其实它的作用和Timer有点相似.都有两种相似的用法:(1)在指定时长后执行某项操作(2)周期性的执行某项操作 AlarmManager对象配合Intent使用,可以定时的开启一个Activity,发送一个

  • Android实现用户圆形头像和模糊背景

    本文实例为大家分享了Android实现用户圆形头像和模糊背景的具体代码,供大家参考,具体内容如下 1.效果展示 2.在build.gradle(Module)中的dependencies里面加入下面依赖 注意:glide依赖的版本 //图片加载框架 implementation 'jp.wasabeef:glide-transformations:2.0.2' //图片模糊效果 compile 'com.github.bumptech.glide:glide:3.7.0' //圆形头像 impl

  • Android权限如何禁止以及友好提示用户开通必要权限详解

    Android权限 Android安全架构规定:默认情况下,任何应用都没有权限执行对其他应用.操作系统或用户有不利影响的任何操作.这包括读写用户的私有数据(联系人,短信,相册,位置).读写其他应用的文件.执行网络访问.使设备保持唤醒状态等等. 如果是一些正常的权限(非高危权限),比如网络访问等在应用清单文件(AndroidManifest.xml)中配置,系统会自动授予, 但是如果有一些高危权限,位置,文件存储,短信等这个时候系统会要求用户授予权限,Android 发出权限请求的方式取决于系统版

  • Android实现简单用户注册案例

    本文实例为大家分享了Android实现简单用户注册的具体代码,供大家参考,具体内容如下 目标: 设计一个用户注册案例.在主界面中对输入的手机号.密码.性别.爱好和城市后,可以在界面二中进行显示. 提示: 1.页面布局的元素用到TextView.EditText.Button.RadioButton.CheckBox.Spinner: 2.通过intent实现主界面跳转到界面二 3.涉及传递多个的数据时,使用Bundle对象作为容器,通过调用Bundle的putString先将数据存储到Bundl

  • Android 用户Session管理的设计方案

    相信大家都知道,每一个App都需要登录,登录信息都保存在本地文件中,然后我们就写一堆的操作SharedPreferences的代码了. 现在,你可以完全抛弃这种方法,一句代码搞定登录信息,用户信息管理.实现全局操作.为你的程序解耦. public void sessionDemo() { // 获取登录信息 TokenInfo token = SessionManager.getDefault().getUserToken(); // 获取用户信息 UserInfo userInfo = Ses

  • 详解Android Studio实现用户登陆界面demo(xml实现)

    使用Android Studio 编写的第一个demo,使用布局文件-xml实现用户登录界面 注:所建工程均为Android 6.0 所以只要是Android 6.0(包括6.0)以上的真机,模拟机都可以使用 Step1:Android Studio 开发环境的搭建: 1.安装JDK (1.8): 2.安装Android studio (3.3.1) 包含 gradle.sdk manage .avd manage : 3.使用sdk manage 下载安装 sdk: 4.使用avd manag

  • Android EditText 监听用户输入完成的实例

    我们都知道, Android EditText输入框,并没有监听用户输入完成的功能,需要我们自己实现. 下面是实现的方法,仅供参考: EditText editText = (EditText) findViewById(R.id.edit); editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, i

  • android实现记住用户名和密码以及自动登录

    毕业刚开始上班接触的第一个项目移动护士站,接到了第一任务就是登录,要用到自动登录功能,所以在这做个记录,以后用的时候直接来粘贴复制,废话少说,直奔主题 先上一下效果图,由于只是实现功能,界面没有美化,见谅 由于xml文件内容,就不展现在这了,自己写一写就好,爸妈再也不用担心我的学习了,so easy package com.sdufe.login; import android.app.Activity; import android.content.Context; import androi

  • Android 多用户详情

    目录 Android 多用户 一.Linux 用户和组 Android 多用户 一.Linux 用户和组 Linux作为一个多用户的操作系统,每个用户在机器上都有一个私有空间,特别是它会拥有配额的磁盘空间,以存储文件.接收私有的mail消息等.Linux必须保证这部分私有空间只对它的拥有者是可见的(类似于银行账户,当然只能对于储户自己可见啦),而且应该确保没有用户可以使用系统应用程序来侵犯其他用户的私有空间(当然也就是不能让别人随便来动我银行账户的资金啦). 在Linux操作系统中,所有的用户都

  • Android百度地图定位、显示用户当前位置

    本文实例为大家分享了Android百度地图定位.显示用户当前位置的工具类,供大家参考,具体内容如下 1.构建定位Option的工具类 import com.baidu.location.LocationClientOption; /** * 建造 LocationClientOption 项 * * @author peter 2018-12-21 10:58 */ public class LocationClientOptionBuilder { private LocationClient

随机推荐