一般来说Android用户比较熟悉的按钮交互方式有两种:单击与长按。双击这个交互且不说合不合理,但需求来了总是要做的。关于这个交互,最先想到的是Android手机系统中,连续点击版本号6次可以打开开发者模式这一场景。这个场景比较简单,只需要计数就好,而我这里的需求,同一个按钮,单击与双击会触发不同的事件。
出于职业嗅觉,首先考虑的是有没有相关API可以调用,查阅了一下,果然找到GestureDetector.OnDoubleTapListener这个接口正适合目前的需求。OnDoubleTapListener的间接子类叫SimpleOnGestureListener,我只需要重写下按钮的onTouch事件,在重写方法里做事件分发即可,于是乎问题迎刃而解:
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
});
GestureDetector gestureDetector = new GestureDetector(Activity.this, new GestureDetector.SimpleOnGestureListener() {
/**
* 发生确定的单击时执行
* @param e
* @return
*/
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {//单击事件
Toast.makeText(Activity.this,"这是单击事件", Toast.LENGTH_SHORT).show();
return super.onSingleTapConfirmed(e);
}
/**
* 双击发生时的通知
* @param e
* @return
*/
@Override
public boolean onDoubleTap(MotionEvent e) {//双击事件
Toast.makeText(Activity.this,"这是单击事件",Toast.LENGTH_SHORT).show();
return super.onDoubleTap(e);
}
/**
* 双击手势过程中发生的事件,包括按下、移动和抬起事件
* @param e
* @return
*/
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return super.onDoubleTapEvent(e);
}
});
假如没有这样的API,我们要自己实现,可以怎么做呢。这里比较绕的地方就是单击和双击事件都要照顾,但二者又有联系和冲突,然后我想了个办法,通过Hander发送不同的消息来标记两个事件,两次点击之间如果小于某个时间差,就认为触发双击事件,单击事件消息的发送延迟略长于这个时间差,如果在这之间触发了双击事件,就撤回单击事件的消息发送,这样单击就不会被执行,代码如下。
public class MainActivity extends Activity {
long mLastTime=0;
long mCurTime=0;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
Toast.makeText(MainActivity.this,"这是单击事件",Toast.LENGTH_LONG).show();
break;
case 2:
Toast.makeText(MainActivity.this,"这是双击事件",Toast.LENGTH_LONG).show();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mLastTime=mCurTime;
mCurTime= System.currentTimeMillis();
if(mCurTime-mLastTime<300){//双击事件
mCurTime =0;
mLastTime = 0;
handler.removeMessages(1);
handler.sendEmptyMessage(2);
}else{//单击事件
handler.sendEmptyMessageDelayed(1, 310);
}
}
});
}
}
跑起来也没什么问题,很OK的样子,不知道大家有没有其他的好办法,可以交流讨论。