setonlongclicklistener longclickable long java android touch move long-press

java - setonlongclicklistener - set longclickable android



¿Detect touch press vs long press vs movement? (9)

Creo que deberías implementar GestureDetector.OnGestureListener como se describe en Usar GestureDetector para detectar Long Touch, Doble toque, Desplazar u otros eventos táctiles en Android y androidsnippets y luego implementar la lógica tap en onSingleTapUp y mover la lógica en eventosScroll

Actualmente estoy jugueteando con la programación de Android, pero tengo un pequeño problema para detectar diferentes eventos táctiles, es decir, una pulsación normal (presionar en la pantalla y soltarla de inmediato), presionar con fuerza (tocar la pantalla y mantener el dedo sobre ella) ) y movimiento (arrastrando en la pantalla).

Lo que quería hacer es tener una imagen (de un círculo) en mi pantalla que pueda arrastrar. Luego, cuando lo presiono una vez (pulsación corta / normal) aparece una tostada con información básica al respecto. Cuando lo presiono, aparece un AlertDialog con una lista para seleccionar una imagen diferente (círculo, rectángulo o triángulo).

Hice una vista personalizada con mi propio OnTouchListener para detectar los eventos y dibujar la imagen en onDraw. El OnTouchListener.onTouch dice algo como esto:

// has a touch press started? private boolean touchStarted = false; // co-ordinates of image private int x, y; public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN) { touchStarted = true; } else if (action == MotionEvent.ACTION_MOVE) { // movement: cancel the touch press touchStarted = false; x = event.getX(); y = event.getY(); invalidate(); // request draw } else if (action == MotionEvent.ACTION_UP) { if (touchStarted) { // touch press complete, show toast Toast.makeText(v.getContext(), "Coords: " + x + ", " + y, 1000).show(); } } return true; }

El problema es que la prensa no funciona como se esperaba, porque cuando toco la pantalla por casualidad también detecta un poco de movimiento y cancela la pulsación y se mueve alrededor de la imagen.

He "pirateado" un poco esto la introducción de una nueva variable "mTouchDelay" que configuré en 0 en ACTION_DOWN, aumento en MOVE y si es> = 3 en MOVE ejecuto mi código de "movimiento". Pero tengo la sensación de que este no es realmente el camino a seguir.

Tampoco descubrí cómo detectar una pulsación larga. El culpable es realmente el movimiento que parece desencadenar siempre.

Para ver un ejemplo de lo que quiero, ver la aplicación de Android "DailyStrip": muestra una imagen de una tira cómica. Puede arrastrarlo si es demasiado grande para la pantalla. Puede tocarlo una vez para que aparezcan algunos controles y presionarlo durante un largo período de tiempo para un menú de opciones.

PD. Estoy intentando que funcione en Android 1.5, ya que mi teléfono solo funciona con 1.5.


De los documentos de Android:

onLongClick ()

De View.OnLongClickListener. Se invoca cuando el usuario toca y retiene el elemento (cuando está en modo táctil), o enfoca el elemento con las teclas de navegación o bola de seguimiento y presiona y mantiene presionada la tecla "enter" o presiona y mantiene presionada la bola de desplazamiento ( por un segundo).

en contacto()

De View.OnTouchListener. Se invoca cuando el usuario realiza una acción calificada como evento táctil, que incluye una prensa, un lanzamiento o cualquier gesto de movimiento en la pantalla (dentro de los límites del elemento).

En cuanto al "movimiento ocurre incluso cuando toco", establecería un delta y me aseguraré de que la Vista haya sido movida por al menos el delta antes de patear el código de movimiento. Si no ha sido, patea el código táctil.


Descubrí esto después de mucha experimentación.

En la inicialización de su actividad:

setOnLongClickListener(new View.OnLongClickListener() { public boolean onLongClick(View view) { activity.openContextMenu(view); return true; // avoid extra click events } }); setOnTouch(new View.OnTouchListener(){ public boolean onTouch(View v, MotionEvent e){ switch(e.getAction & MotionEvent.ACTION_MASK){ // do drag/gesture processing. } // you MUST return false for ACTION_DOWN and ACTION_UP, for long click to work // you can return true for ACTION_MOVEs that you consume. // DOWN/UP are needed by the long click timer. // if you want, you can consume the UP if you have made a drag - so that after // a long drag, no long-click is generated. return false; } }); setLongClickable(true);


Estaba buscando una solución similar y esto es lo que sugeriría. En el método OnTouch, registre la hora para el evento MotionEvent.ACTION_DOWN y luego para MotionEvent.ACTION_UP, registre la hora otra vez. De esta manera puede establecer su propio umbral también. Después de experimentar algunas veces sabrá el tiempo máximo en milímetros que necesitaría para grabar un simple toque y puede usarlo en movimiento u otro método como desee.

Espero que esto haya ayudado. Comente si utilizó un método diferente y resolvió su problema.


Estaba lidiando con este desastre después de querer que Longclick no termine con un evento de clic.

Esto es lo que hice.

public boolean onLongClick(View arg0) { Toast.makeText(getContext(), "long click", Toast.LENGTH_SHORT).show(); longClicked = true; return false; } public void onClick(View arg0) { if(!longClicked){ Toast.makeText(getContext(), "click", Toast.LENGTH_SHORT).show(); } longClick = false; // sets the clickability enabled } boolean longClicked = false;

Es un truco pero funciona.


Este código puede distinguir entre clic y movimiento (arrastrar, desplazarse). En onTouchEvent establece un indicador isOnClick, y las coordenadas iniciales X, Y en ACTION_DOWN. Borre la bandera en ACTION_MOVE (teniendo en cuenta que a menudo se detecta movimiento involuntario que se puede resolver con un const).

private float mDownX; private float mDownY; private final float SCROLL_THRESHOLD = 10; private boolean isOnClick; @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: mDownX = ev.getX(); mDownY = ev.getY(); isOnClick = true; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (isOnClick) { Log.i(LOG_TAG, "onClick "); //TODO onClick code } break; case MotionEvent.ACTION_MOVE: if (isOnClick && (Math.abs(mDownX - ev.getX()) > SCROLL_THRESHOLD || Math.abs(mDownY - ev.getY()) > SCROLL_THRESHOLD)) { Log.i(LOG_TAG, "movement detected"); isOnClick = false; } break; default: break; } return true; }

Para LongPress como se sugirió anteriormente, GestureDetector es el camino a seguir. Verifique esta pregunta y respuesta:

Detectando una pulsación larga con Android


GestureDetector.SimpleOnGestureListener tiene métodos para ayudar en estos 3 casos;

GestureDetector gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { //for single click event. @Override public boolean onSingleTapUp(MotionEvent motionEvent) { return true; } //for detecting a press event. Code for drag can be added here. @Override public void onShowPress(MotionEvent e) { View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); ClipData clipData = ClipData.newPlainText("..", "..."); clipboardManager.setPrimaryClip(clipData); ConceptDragShadowBuilder dragShadowBuilder = new CustomDragShadowBuilder(child); // drag child view. child.startDrag(clipData, dragShadowBuilder, child, 0); } //for detecting longpress event @Override public void onLongPress(MotionEvent e) { super.onLongPress(e); } });


Si necesita distinguir entre un clic, presionar prolongadamente y un desplazamiento, use GestureDetector

La actividad implementa GestureDetector.OnGestureListener

luego crea detector en onCreate por ejemplo

mDetector = new GestureDetectorCompat(getActivity().getApplicationContext(),this);

luego opcionalmente configureOnTouchListener en su Vista (por ejemplo, vista web) donde

onTouch(View v, MotionEvent event) { return mDetector.onTouchEvent(event); }

y ahora puede usar Anular desplazamiento, En vuelo, mostrarPresionar (detectar pulsación prolongada) o enToma única (detectar un clic)