天天看点

多次点击事件

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键,则退出,否则不对此响应。

改进的方式

上面 这种方式有个缺陷,如果要实现多次点击,那么就需要定义存贮多个事件点的变量,很显然不适合多次点击的处理。 不过我们如果对此经过一些改进,还是可以很好的解决这个问题的。 以下为项目中的部分相关代码: 首先定义一个集合,存储所有临时的数据,这里用了Android中推荐的LongSparseArray

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

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

key = System.currentTimeMillis();
RecordBean recordBean = new RecordBean(key);//千万不要采取定义一堆变量的方式保存数据,而应该选择一个合适的Model保存所有相关的信息
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 && new File(removedBean.pcmPath).delete()) L.i("成功删除pcm文件");
	if (removedBean.aacPath != null && new File(removedBean.aacPath).delete()) L.i("成功删除aac文件");
}
           

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

使用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击事件条件**;
}
           

2017-8-22

来自为知笔记(Wiz)