End

多次点击事件 [MD]

博文地址

我的GitHub 我的博客 我的微信 我的邮箱
baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

目录

多次点击事件

Android给我们提供了单次点击事件,虽然在设置中我们有发现多次点击事件的案例,如多次点击"版本号"后启用开发者模式、多次点击"Android版本"后显示版本动画,但Android本身并没有提供多次点击事件的实现。有如下几种实现方式。

定义存贮多个事件点的成员变量

双击事件案例

首先以双击事件为例说明。

定义一个变量,存贮第一次点击时的事件(这里只需要存储点击时间),如果第二次点击时的时间和此变量中记录的时间的间隔小于500毫秒,则认为是双击事件。

private long startClickTime;

public void onClickView() {
   long nextClickTime = SystemClock.uptimeMillis();
   if (startClickTime <= 0) startClickTime = SystemClock.uptimeMillis();
   else {
      if (nextClickTime - startClickTime < 500) {
         Toast.makeText(this, "双击", Toast.LENGTH_SHORT).show();
         startClickTime = 0L;
      } else startClickTime = nextClickTime;
   }
}

这种处理方式经常用在这种场景下:用户在主界面点击一次BACK键后,提示用户"再点击一次退出",如果用户在2s内再次点击了一次BACK键,则退出,否则不对此响应。

改进的方式,使用 LongSparseArray

上面这种方式有个缺陷,如果要实现多次点击,那么就需要定义存贮多个事件点的变量,很显然不适合多次点击的处理。
不过我们如果对此经过一些改进,还是可以很好的解决这个问题的。

首先定义一个集合,存储所有临时的数据,这里用了Android中推荐的 LongSparseArray

public static LongSparseArray<RecordBean> RECORD_LIST = new LongSparseArray<>();

其中,键为当前时间,以保证唯一性

key = System.currentTimeMillis();
RecordBean recordBean = new RecordBean(key);
RECORD_LIST.put(key, recordBean);

既然都保存到了集合中,所以读取时就很方便、灵活了

Long key = RECORD_LIST.keyAt(i);
RecordBean recordBean = RECORD_LIST.get(key);

由于我们只需要保存指定数量的临时数据,所以当集合中的数据超过指定数量时,我们要移除集合中最靠前的数据

if (RECORD_LIST != null && RECORD_LIST.size() > MAX_SIZE_OF_SAVED_FILES_IN_SDCARD) {
    RecordBean removedBean = RECORD_LIST.valueAt(0);
    RECORD_LIST.removeAt(0);
    if (removedBean.pcmPath != null) {
        //...
    }
}

后面的判断就和上面的基本一致了。

使用Google提供的api中采用的算法

这个算法比较巧妙,主要是利用了System.arraycopy进行自复制的功能,可以借鉴一下。

为了实现n次点击事件,我们需要定义一个长度为n的数组,每点击一次就将数组里的内容整体向左移动一格,然后给数组的最后一个元素赋值当前的时间,如果当前时间(最后一个元素记录的时间)减去第0个元素记录的时间小于500毫秒的话,那么证明在500毫秒内点击了n次。

private long[] mHits = new long[4];
private static final int MAX_TIME = 500;

public void onClickView() {
   Toast.makeText(this, "击", Toast.LENGTH_SHORT).show();
   //复制数组中的元素,从第1个位置开始,目标地址是第0个位置,复制的长度为数组长度-1(也就是舍弃掉第0个元素)
   System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
   //给数组最后一个位置赋值
   mHits[mHits.length - 1] = SystemClock.uptimeMillis();
   //判断数组第一个位置的时间与当前时间的差是否小于500毫秒,假如小于的话,就认为是多次点击事件
   if (SystemClock.uptimeMillis() - mHits[0] < MAX_TIME){
       //N击事件条件触发。
       //如果此事件只需触发一次(比如5次点击之后再点击5次才触发下一次,而不是之后再点击一次就触发下一次),需要在这里重置数据
   }
}

2017-03-23

posted @ 2017-03-23 17:50  白乾涛  阅读(643)  评论(0编辑  收藏  举报