双击事件代码如下:
long[] mHits = new long[2];
/**
* 为主界面的回退事件做处理
*/
@Override
public void onBackPressed() {
System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
mHits[mHits.length - 1] = SystemClock.uptimeMillis();
if (SystemClock.uptimeMillis() - mHits[0] <= 2000) {
// 如果第一次点击时间和第二次点击时间相差在2000ms之内的话,就可以视为双击事件
finish();
} else {
Toast.makeText(getApplicationContext(), "再点一次退出", Toast.LENGTH_SHORT).show();
}
}
涉及到的核心方法是System.arraycopy(Object src, int srcPos, Object dst, int dstPos, int length);
含义:
从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。从 src 引用的源数组到 dest 引用的目标数组,数组组件的一个子序列被复制下来。被复制的组件的编号等于 length 参数。源数组中位置在 srcPos 到 srcPos+length-1 之间的组件被分别复制到目标数组中的 destPos 到 destPos+length-1 位置
- Object src:原数组。
- int srcPos:源数组中的起始位置。
- Object dst:目标数组。
- int dstPos:目标数据中的起始位置
- int length:要复制的数组元素的数量。
ok,来看看原理吧
- 首先,我们创建了一个length为2的空数组,方便存放点击时间,这时候里边元素默认都是0
- 接下来我们给数组第二个元素存入当前时间即SystemClock.uptimeMillis(),注意,此时第一个元素仍然是0
- 接下来就是数组复制了,这也是System.arraycopy的核心用处了,让srcPos=1,length=mHits.length - 1,就是我们需要从1开始复制length个长度的元素(当然,此处只有一个元素),复制到的数组也是mHits,即从第一个元素开始存放之前需要复制的元素(即1至length元素)。
- 上边其实就相当于一个FIFO的数组,第二个元素的点击时间比第一个靠后,每点击一次,第一个元素出栈,其他元素角标往前移,而当前点击时间存在最后一个,完成数组更新
- 所以上边的数组只会存放当前点击时间和之前一次的点击时间,那么我们只需要两者比较时间差就行了
了解了上面的原理之后,多击事件也是手到擒来的啦,
long[] mHits = new long[N];
public void isNClick(View v){
System.arraycopy(mHtits,1,mHits,0,mHits.length-1);
mHits[mHits.length-1] = SystemClock.upTimeMillis();
if(mHits[mHits.length-1]-mHits[0]<=500){
//如果第一次点击时间和最后一次点击时间相差在500ms之内的话,就可以视为多击事件
}
}