Android:不同按钮触发MotionEvent时getDownTime()的使用疑问
嘿,我来帮你理清楚Android里getDownTime()在多按钮触摸场景下的行为~
多按钮场景下MotionEvent.getDownTime()的行为解析
核心原理先搞懂
MotionEvent.getDownTime()返回的是当前触摸事件所属的触摸序列中,第一次ACTION_DOWN事件的时间戳。这里的「触摸序列」是指从用户按下某个触摸点(比如手指按在按钮A上)开始,到这个触摸点被抬起(ACTION_UP)或者取消(ACTION_CANCEL)为止的整个事件流——每个独立的触摸操作(比如先后按不同按钮、同时按多个按钮)都是各自独立的触摸序列,互相不干扰。
不同场景的具体表现
我分两种常见场景给你拆解:
- 场景1:先后点击不同按钮
当你先按下按钮A(触发A的ACTION_DOWN),抬起后再按下按钮B(触发B的ACTION_DOWN):- 按钮A的ACTION_UP事件中,
getDownTime()是A的ACTION_DOWN的时间,计算的是A被按住的时长; - 按钮B的ACTION_UP事件中,
getDownTime()是B的ACTION_DOWN的时间,和按钮A的事件完全无关。
- 按钮A的ACTION_UP事件中,
- 场景2:同时按下多个按钮(多点触摸)
Android支持多点触摸,每个触摸点对应一个独立的触摸序列,每个序列有自己的getDownTime():- 假设你用手指1按按钮A,手指2按按钮B,两个ACTION_DOWN事件会分别携带不同的
pointerId; - 每个按钮的触摸事件(不管是哪个手指触发的),对应的
getDownTime()只属于该触摸点的初始按下时间,互相不干扰。
- 假设你用手指1按按钮A,手指2按按钮B,两个ACTION_DOWN事件会分别携带不同的
结合你的代码优化建议
你的示例里只在ACTION_DOWN调用了btn1_down(),要准确计算按钮按住时长,建议在ACTION_UP时直接用event.getEventTime() - event.getDownTime()来计算,同时注意消费触摸事件避免丢失:
Button btn1 = findViewById(R.id.btn1); Button btn2 = findViewById(R.id.btn2); // btn1的触摸监听 btn1.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d("Btn1", "按下,downTime: " + event.getDownTime()); return true; // 返回true确保整个触摸序列的事件都传递给当前按钮 case MotionEvent.ACTION_UP: long holdDuration = event.getEventTime() - event.getDownTime(); Log.d("Btn1", "抬起,按住时长: " + holdDuration + "ms"); // 此处添加你的后续处理逻辑 return true; } return false; } }); // btn2的触摸监听完全独立于btn1,逻辑一致 btn2.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d("Btn2", "按下,downTime: " + event.getDownTime()); return true; case MotionEvent.ACTION_UP: long holdDuration = event.getEventTime() - event.getDownTime(); Log.d("Btn2", "抬起,按住时长: " + holdDuration + "ms"); return true; } return false; } });
常见误区提醒
- 不要误以为
getDownTime()是全局的最近一次按下时间——它是绑定到当前触摸序列的,每个按钮的触摸事件序列都是独立的,所以不同按钮的getDownTime()不会互相覆盖。 - 如果触摸事件被中断(比如按下按钮后滑动到按钮外触发ACTION_CANCEL),此时
getDownTime()依然是该序列的初始按下时间,同样可以计算到中断时的按住时长。
内容的提问来源于stack exchange,提问作者Heisenbugs
相关产品推荐
相关产品推荐

