为什么android onLongPress总是在onDoubleTap之后触发?
我根据以下代码将 onLongPress 和 onDoubleTap 操作放置在按钮上:
...
GestureDetector detector = new GestureDetector(this, new TapDetector());
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
detector = new GestureDetector(this, new TapDetector());
...
}
private class TapDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDoubleTap(MotionEvent e) {
// Do something
return true;
}
@Override
public void onLongPress(MotionEvent e) {
// Do something
}
}
Button incomeButton = (Button) findViewById(R.id.income);
button.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
detector.onTouchEvent(event);
return true;
}
});
我总是看到 onLongPress 在 onDoubleClick 触发并执行后触发。这种违反直觉的行为的原因是什么以及如何避免?
已更新 我已将源代码更改为更具体
public class MainActivity extends Activity {
private GestureDetector detector;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
detector = new GestureDetector(this, new TapDetector());
Button button = (Button) findViewById(R.id.button);
button.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("************* onTouch *************");
detector.onTouchEvent(event);
return true;
}
});
}
class TapDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public void onLongPress(MotionEvent e) {
System.out.println("************* onLongPress *************");
}
@Override
public boolean onDoubleTap(MotionEvent e) {
System.out.println("************* onDoubleTap *************");
Intent intent = new Intent();
intent.setClass(getApplicationContext(), NewActivity.class);
intent.putExtra("parameterName", "parameter");
startActivity(intent);
return true;
}
}
}
这是我单击 onDoubleTap 后的日志。你可以在最后看到 onLongPress - 我从不点击它。
I/System.out( 1106): ************* onTouch *************
I/System.out( 1106): ************* onTouch *************
I/System.out( 1106): ************* onTouch *************
I/System.out( 1106): ************* onDoubleTap *************
I/ActivityManager( 59): Starting activity: Intent { cmp=my.tapdetector/.NewActivity (has extras) }
I/ActivityManager( 59): Displayed activity my.tapdetector/.NewActivity: 324 ms (total 324 ms)
I/System.out( 1106): ************* onLongPress *************
更新我找到了解决方案。为了避免 onLongPress 触发,需要进行两项更改:
首先: detector.setIsLongpressEnabled(true);在onTouch(View v, MotionEvent event)中
button.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("************* onTouch *************");
detector.onTouchEvent(event);
detector.setIsLongpressEnabled(true);
return true;
}
});
第二:添加 detector.setIsLongpressEnabled(false);在 onDoubleTap(MotionEvent e) 中
public boolean onDoubleTap(MotionEvent e) {
detector.setIsLongpressEnabled(false);
System.out.println("************* onDoubleTap *************");
Intent intent = new Intent();
intent.setClass(getApplicationContext(), NewActivity.class);
intent.putExtra("parameterName", "parameter");
startActivity(intent);
return true;
}
I have onLongPress and onDoubleTap actions placed on the button according to this code:
...
GestureDetector detector = new GestureDetector(this, new TapDetector());
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
detector = new GestureDetector(this, new TapDetector());
...
}
private class TapDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDoubleTap(MotionEvent e) {
// Do something
return true;
}
@Override
public void onLongPress(MotionEvent e) {
// Do something
}
}
Button incomeButton = (Button) findViewById(R.id.income);
button.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
detector.onTouchEvent(event);
return true;
}
});
I always see onLongPress fired after onDoubleClick fired and executed. What is the reason of such counterintuitive behavior and how to avoid it?
UPDATED
I have changed my source code to be more specific
public class MainActivity extends Activity {
private GestureDetector detector;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
detector = new GestureDetector(this, new TapDetector());
Button button = (Button) findViewById(R.id.button);
button.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("************* onTouch *************");
detector.onTouchEvent(event);
return true;
}
});
}
class TapDetector extends GestureDetector.SimpleOnGestureListener {
@Override
public void onLongPress(MotionEvent e) {
System.out.println("************* onLongPress *************");
}
@Override
public boolean onDoubleTap(MotionEvent e) {
System.out.println("************* onDoubleTap *************");
Intent intent = new Intent();
intent.setClass(getApplicationContext(), NewActivity.class);
intent.putExtra("parameterName", "parameter");
startActivity(intent);
return true;
}
}
}
This is a log after onDoubleTap I clicked. You can see onLongPress at the end - I never click it.
I/System.out( 1106): ************* onTouch *************
I/System.out( 1106): ************* onTouch *************
I/System.out( 1106): ************* onTouch *************
I/System.out( 1106): ************* onDoubleTap *************
I/ActivityManager( 59): Starting activity: Intent { cmp=my.tapdetector/.NewActivity (has extras) }
I/ActivityManager( 59): Displayed activity my.tapdetector/.NewActivity: 324 ms (total 324 ms)
I/System.out( 1106): ************* onLongPress *************
UPDATE I have found the solution. To avoid onLongPress firing two changes needs to be done:
First: detector.setIsLongpressEnabled(true); in onTouch(View v, MotionEvent event)
button.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("************* onTouch *************");
detector.onTouchEvent(event);
detector.setIsLongpressEnabled(true);
return true;
}
});
Second: add detector.setIsLongpressEnabled(false); in onDoubleTap(MotionEvent e)
public boolean onDoubleTap(MotionEvent e) {
detector.setIsLongpressEnabled(false);
System.out.println("************* onDoubleTap *************");
Intent intent = new Intent();
intent.setClass(getApplicationContext(), NewActivity.class);
intent.putExtra("parameterName", "parameter");
startActivity(intent);
return true;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从技术上讲,这种情况不应该发生,
因为在发生 ACTION_DOWN 或 ACTION_UP 事件时,所有 LONG_PRESS 消息事件都会从队列中删除。因此,在第二次点击时,以下代码将删除长按事件。
Technically this shouldn't happen
because on the ACTION_DOWN or ACTION_UP event, all of the LONG_PRESS messages events are removed from the queue. So on the second tap the following code will remove the long press events.
您总是会看到 onLongPress 被触发,因为在代码中您在使用 onDoubleTap 事件之前启动了一个意图。
您可以通过以下方式禁用 onLongPress
public void setIsLongpressEnabled (boolean isLongpressEnabled)
并使用 onDown 方法来执行您的操作。
You see always the onLongPress fired because in your code you launch an intent before of consuming the onDoubleTap event.
You can disable onLongPress by
public void setIsLongpressEnabled (boolean isLongpressEnabled)
and use the onDown method for performing your action.