当前位置: 代码迷 >> Android >> 第三种,谷歌程序员的写法。
  详细解决方案

第三种,谷歌程序员的写法。

热度:16   发布时间:2016-04-28 02:38:32.0
Android中实现双击(多击)事件

第一种,容易想到的方法。

  要实现双击,你需要保存第一次点击时的时间,需要使用到变量,之后便是与第二次点击时的时间比较,看时间间隔是否在你设定的时间内(比如500ms)。
	long firstClickTime = 0;	long secondClickTime = 0;	public void click1(View view) {		if (firstClickTime > 0) {			secondClickTime = SystemClock.uptimeMillis();			if (secondClickTime - firstClickTime < 500) {				Toast.makeText(this, "第一种双击方式", 0).show();			}			firstClickTime = 0;			return ;		}		firstClickTime = SystemClock.uptimeMillis();				new Thread(new Runnable() {						@Override			public void run() {				//				try {					Thread.sleep(500);					firstClickTime = 0;				} catch (InterruptedException e) {					// TODO Auto-generated catch block					e.printStackTrace();				}							}		}).start();	}
  双击事件(多击事件)中有两个重要的问题需要考虑:第一次点击的时间,最后(如何知道是“最后”)点击的时间;点击一次后,等待一段时间(比如2s),再次双击(多击)如何保证得到正确的响应。
  上面的代码解决了这两个问题,但不够效率,也很复杂。它是通过一个变量存储第一次点击的时间,通过判断这个变量的大小来判断是不是第二次点击,解决第一个问题;再加上子线程的sleep方法,500ms内如果没有第二次点击,变量就重置了,解决了第二个问题。
  但是这种方式解决双击事件还算凑合,那么三击、四击……如何解决了?

第二种,换种方式存储变量

<pre name="code" class="java">	List<Long> times = new ArrayList<Long>();	public void click2(View view) {		times.add(SystemClock.uptimeMillis());		if (times.size() == 2) {			//已经完成了一次双击,list可以清空了			if (times.get(times.size()-1)-times.get(0) < 500) {				times.clear();				Toast.makeText(this, "第二种双击方式", 0).show();			} else {				//这种情况下,第一次点击的时间已经没有用处了,第二次就是“第一次”				times.remove(0);			}		}	}


  在第二种方式中,使用List存放点击时的时间。现在来分析一下这个实现的原理:

  1、如何判断是第二次点击?

  通过链表的长度,每次点击list的长度加1,当为2时,表示点击了两次。

  2、如何消除间隔一段时间的点击事件的影响?

  如果是正常的双击,点击两次就完成一次“轮回”,之前保存的时间数据已经使用完毕了,需要清除掉,具体操作就是将List清空。而如果是点击一次后,第二次点击相隔时间较长,那个第一次点击的时间已经没有用处了,就直接将第二次点击视为“第一次”点击,具体而言就是去掉第1次的点击事件。

  这个方法,比起第一种方法效率要好得多,而且非常容易扩展到三击、四击……事件。比如:
<pre name="code" class="java">	List<Long> times = new ArrayList<Long>();	public void click2(View view) {		times.add(SystemClock.uptimeMillis());		if (times.size() == 3) {			if (times.get(times.size()-1)-times.get(0) < 500) {				times.clear();				Toast.makeText(this, "三击方式", 0).show();			} else {				times.remove(0);			}		}	}


改变的只是判断条件。

第三种,谷歌程序员的写法。

  下面是谷歌所写的三击方法,我改写成了双击的方法
	/**	 * 双击事件、多击事件	 */	//存储时间的数组	long[] mHits = new long[2];	public void doubleClick() {		// 双击事件响应		/**		 * arraycopy,拷贝数组 		 * src 要拷贝的源数组		 * srcPos 源数组开始拷贝的下标位置		 * dst 目标数组		 * dstPos 开始存放的下标位置		 * length 要拷贝的长度(元素的个数)		 *		 */		//实现数组的移位操作,点击一次,左移一位,末尾补上当前开机时间(cpu的时间)		System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);		mHits[mHits.length - 1] = SystemClock.uptimeMillis();		//双击事件的时间间隔500ms		if (mHits[0] >= (SystemClock.uptimeMillis() - 500)) {            //双击后具体的操作			//do		}	}
  非常简洁,思想差不多,不过谷歌工程师是利用数组移位操作来消除第二个问题的影响的。而要实现多击事件,只需修改数组长度即可。


  相关解决方案