Saltar ImageView mientras arrastra. Los valores de getX () y getY () saltan
He creado un onTouchListener para arrastrar Vistas. Las imágenes se arrastran sin problemas si uso getRawX()
y getRawY()
. El problema es que la imagen salta al segundo puntero cuando coloca un segundo puntero hacia abajo y luego levanta el primer puntero.
Este onTouchListener intenta corregir ese problema siguiendo la pista del pointerId
. El problema con este onTouchListener es mientras arrastra un ImageView, el ImageView salta alrededor bastante loco. Los getX()
y getY()
saltan alrededor.
- Android: Detectar el botón ACTION_UP fuera del evento
- ¿Cómo manejar eventos de toque en un fragmento?
- Android: ImageView getID (); Devolver entero
- Android: OnTouch, MotionEvent.ACTION_MOVE no está reconocido?
- GC y onTouch causan un error de señal fatal 11 (SIGSEGV) en la aplicación que utiliza ffmpeg a través de ndk
Siento que estoy haciendo esto correctamente. No quiero tener que escribir una vista personalizada para esto porque ya he implementado un scaleGestureDetector y escribió un rotateGestureDetector personalizado que funciona. Todo funciona bien, pero necesito arreglar el problema que obtengo al usar getRawX()
y getRawY()
.
¿Alguien sabe lo que estoy haciendo mal aquí?
Aquí está mi onTouchListener:
final View.OnTouchListener onTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { relativeLayoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams(); final int action = event.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { final float x = event.getX(); final float y = event.getY(); // Where the user started the drag lastX = x; lastY = y; activePointerId = event.getPointerId(0); break; } case MotionEvent.ACTION_MOVE: { // Where the user's finger is during the drag final int pointerIndex = event.findPointerIndex(activePointerId); final float x = event.getX(pointerIndex); final float y = event.getY(pointerIndex); // Calculate change in x and change in y final float dx = x - lastX; final float dy = y - lastY; // Update the margins to move the view relativeLayoutParams.leftMargin += dx; relativeLayoutParams.topMargin += dy; v.setLayoutParams(relativeLayoutParams); // Save where the user's finger was for the next ACTION_MOVE lastX = x; lastY = y; v.invalidate(); break; } case MotionEvent.ACTION_UP: { activePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_CANCEL: { activePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_POINTER_UP: { // Extract the index of the pointer that left the touch sensor final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; final int pointerId = event.getPointerId(pointerIndex); if(pointerId == activePointerId) { // This was our active pointer going up. Choose a new // active pointer and adjust accordingly final int newPointerIndex = pointerIndex == 0 ? 1 : 0; lastX = (int) event.getX(newPointerIndex); lastY = (int) event.getY(newPointerIndex); activePointerId = event.getPointerId(newPointerIndex); } break; } } return true; } }; image1.setOnTouchListener(onTouchListener);
- OnTouchListener de una vista vs onTouchEvent
- Android: ¿Qué uso tiene AnchorView de MediaController?
- Android principiante: toque eventos en android gridview
- Problema en OnTouchListener para ImageView
- Ocultar teclado en android mientras se toca fuera Editar área de texto
- ¿Es OnTouchListener más rápido que OnClickListener?
- Cambiar la altura del diseño relativo con la misma velocidad que el dedo del usuario Se mueve en el diseño
- ¿Cómo hacer algo repetidamente mientras se presiona un botón?
La cuestión era simple, pero inesperada. getRawX/Y()
devuelve coordenadas absolutas, mientras que getX/Y()
devuelve las coordenadas relativas a la vista. Me gustaría mover la vista, restablecer lastX/Y
, y la imagen no estaría en el mismo lugar más así que cuando recibo nuevos valores que estaría fuera. En este caso sólo necesitaba donde originalmente presioné la imagen (no es el caso cuando se usa `getRawX / Y ').
Por lo tanto, la solución era simplemente eliminar lo siguiente:
// Save where the user's finger was for the next ACTION_MOVE lastX = x; lastY = y;
Espero que esto ayude a alguien en el futuro, porque he visto a otros con este problema, y tenían un código similar para mí (reiniciar lastX/Y
)
Tengo una sugerencia y creo que va a ayudar.
invalidate() : does only redrawing a view,doesn't change view size/position.
Lo que debe usar es requestLayout()
: hace el proceso de medición y diseño. & Pienso que requestLayout()
será llamado cuando llamada setLayoutParams()
;
Por lo tanto, intente eliminar v.invalidate()
O intente usar el view.layout(left,top,right,bottom)
lugar de configurar layoutParams.
Después de una gran cantidad de investigación, encontré que este era el problema, getRawX es absoluta y getX es relativa a la vista. Por lo tanto, utilizar esto para transformar uno a otro
//RawX = getX + View.getX event.getRawX == event.getX(event.findPointerIndex(ptrID1))+view.getX()
- Reutilizar código al usar pantallas en Libgdx
- Error de "sistema de archivos de sólo lectura" al escribir en la tarjeta SD