用Android检测一个长按

我目前正在使用

onTouchEvent(MotionEvent event){ } 

检测用户何时按下我的glSurfaceView有没有办法检测什么时候长按。 我猜如果我在开发文档中找不到太多,那么这将是某种方法的工作。 就像注册ACTION_DOWN和看ACTION_UP之前的时间一样。

如何检测使用opengl-es的长时间按下android?

尝试这个:

 final GestureDetector gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() { public void onLongPress(MotionEvent e) { Log.e("", "Longpress detected"); } }); public boolean onTouchEvent(MotionEvent event) { return gestureDetector.onTouchEvent(event); }; 

手势检测器是最好的解决scheme。

这是一个有趣的select。 在每个ACTION_DOWN的 onTouchEvent时间表中,一个Runnable在1秒内运行。 在每个ACTION_UPACTION_MOVE上 ,取消预定的Runnable。 如果从ACTION_DOWN事件中取消发生less于1 ,Runnable将不会运行。

 final Handler handler = new Handler(); Runnable mLongPressed = new Runnable() { public void run() { Log.i("", "Long press!"); } }; @Override public boolean onTouchEvent(MotionEvent event, MapView mapView){ if(event.getAction() == MotionEvent.ACTION_DOWN) handler.postDelayed(mLongPressed, 1000); if((event.getAction() == MotionEvent.ACTION_MOVE)||(event.getAction() == MotionEvent.ACTION_UP)) handler.removeCallbacks(mLongPressed); return super.onTouchEvent(event, mapView); } 

当你的意思是用户按下,你的意思是一个点击? 点击是当用户按下然后立即抬起手指。 因此它包含两个onTouch事件。 您应该保存onTouchEvent的使用,以便在初始触摸或发布后发生的事情。

因此,如果是点击,您应该使用onClickListener。

你的答案是类似的:使用onLongClickListener。

我有一个代码检测点击,长时间点击和移动。 这是上面给出的答案和我从偷窥到每个文档页面所做的更改的组合。

 //Declare this flag globally boolean goneFlag = false; //Put this into the class final Handler handler = new Handler(); Runnable mLongPressed = new Runnable() { public void run() { goneFlag = true; //Code for long click } }; //onTouch code @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: handler.postDelayed(mLongPressed, 1000); //This is where my code for movement is initialized to get original location. break; case MotionEvent.ACTION_UP: handler.removeCallbacks(mLongPressed); if(Math.abs(event.getRawX() - initialTouchX) <= 2 && !goneFlag) { //Code for single click return false; } break; case MotionEvent.ACTION_MOVE: handler.removeCallbacks(mLongPressed); //Code for movement here. This may include using a window manager to update the view break; } return true; } 

我确认它是在我自己的应用程序中使用的。

MSquare的解决scheme只有在您持有特定像素的情况下才有效,但对于最终用户来说这是一个不合理的期望,除非他们使用鼠标(他们不会使用手指)。

所以我在DOWN和UP之间的距离加了一点阈值,以防MOVE动作。

 final Handler longPressHandler = new Handler(); Runnable longPressedRunnable = new Runnable() { public void run() { Log.e(TAG, "Long press detected in long press Handler!"); isLongPressHandlerActivated = true; } }; private boolean isLongPressHandlerActivated = false; private boolean isActionMoveEventStored = false; private float lastActionMoveEventBeforeUpX; private float lastActionMoveEventBeforeUpY; @Override public boolean dispatchTouchEvent(MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) { longPressHandler.postDelayed(longPressedRunnable, 1000); } if(event.getAction() == MotionEvent.ACTION_MOVE || event.getAction() == MotionEvent.ACTION_HOVER_MOVE) { if(!isActionMoveEventStored) { isActionMoveEventStored = true; lastActionMoveEventBeforeUpX = event.getX(); lastActionMoveEventBeforeUpY = event.getY(); } else { float currentX = event.getX(); float currentY = event.getY(); float firstX = lastActionMoveEventBeforeUpX; float firstY = lastActionMoveEventBeforeUpY; double distance = Math.sqrt( (currentY - firstY) * (currentY - firstY) + ((currentX - firstX) * (currentX - firstX))); if(distance > 20) { longPressHandler.removeCallbacks(longPressedRunnable); } } } if(event.getAction() == MotionEvent.ACTION_UP) { isActionMoveEventStored = false; longPressHandler.removeCallbacks(longPressedRunnable); if(isLongPressHandlerActivated) { Log.d(TAG, "Long Press detected; halting propagation of motion event"); isLongPressHandlerActivated = false; return false; } } return super.dispatchTouchEvent(event); } 
 setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { int action = MotionEventCompat.getActionMasked(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: longClick = false; x1 = event.getX(); break; case MotionEvent.ACTION_MOVE: if (event.getEventTime() - event.getDownTime() > 500 && Math.abs(event.getX() - x1) < MIN_DISTANCE) { longClick = true; } break; case MotionEvent.ACTION_UP: if (longClick) { Toast.makeText(activity, "Long preess", Toast.LENGTH_SHORT).show(); } } return true; } }); 

我已经创build了一个由实际查看源启发的代码片段 ,它可以自定义延迟来可靠地检测长时间的点击/按压。 但是在Kotlin:

 val LONG_PRESS_DELAY = 500 val handler = Handler() var boundaries: Rect? = null var onTap = Runnable { handler.postDelayed(onLongPress, LONG_PRESS_DELAY - ViewConfiguration.getTapTimeout().toLong()) } var onLongPress = Runnable { // Long Press } override fun onTouch(view: View, event: MotionEvent): Boolean { when (event.action) { MotionEvent.ACTION_DOWN -> { boundaries = Rect(view.left, view.top, view.right, view.bottom) handler.postDelayed(onTap, ViewConfiguration.getTapTimeout().toLong()) } MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { handler.removeCallbacks(onLongPress) handler.removeCallbacks(onTap) } MotionEvent.ACTION_MOVE -> { if (!boundaries!!.contains(view.left + event.x.toInt(), view.top + event.y.toInt())) { handler.removeCallbacks(onLongPress) handler.removeCallbacks(onTap) } } } return true }