Tengo una vista personalizada derivada de Ver. Me gustaría recibir una notificación cuando se haga clic en la vista y la ubicación x, y de donde ocurrió el clic. Lo mismo ocurre con los clics largos.
Parece que para hacer esto, necesito anularlo onTouchEvent()
. Sin embargo, ¿no hay forma de obtener la ubicación x, y del evento de an OnClickListener
?
Si no es así, ¿cuál es una buena forma de saber si un evento de movimiento es un clic "real" frente a un clic largo, etc.? El onTouchEvent
genera muchos eventos en rápida sucesión, etc.
false
para que no bloquee los eventos táctiles? (View.OnTouchListener.onTouch devuelve verdadero si el oyente ha consumido el evento, falso en caso contrario.)OnClickListener
se dispara cuando se suelta el dedo, por lo tanto,ACTION_UP
pero con limitaciones: si se realizó el gesto de deslizar (deslizar),OnClickListener
no se dispara peroACTION_UP
aún se procesará.(event.getX(), event.getY())
pero no se escribe en la posición correcta.Ejemplo completo
A las otras respuestas les faltan algunos detalles. Aquí tienes un ejemplo completo.
public class MainActivity extends AppCompatActivity { // class member variable to save the X,Y coordinates private float[] lastTouchDownXY = new float[2]; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // add both a touch listener and a click listener View myView = findViewById(R.id.my_view); myView.setOnTouchListener(touchListener); myView.setOnClickListener(clickListener); } // the purpose of the touch listener is just to store the touch X,Y coordinates View.OnTouchListener touchListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // save the X,Y coordinates if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { lastTouchDownXY[0] = event.getX(); lastTouchDownXY[1] = event.getY(); } // let the touch event pass on to whoever needs it return false; } }; View.OnClickListener clickListener = new View.OnClickListener() { @Override public void onClick(View v) { // retrieve the stored coordinates float x = lastTouchDownXY[0]; float y = lastTouchDownXY[1]; // use the coordinates for whatever Log.i("TAG", "onLongClick: x = " + x + ", y = " + y); } }; }
Resumen
OnTouchListener
OnClickListener
fuente
Anular onTouchEvent (MotionEvent ev)
Entonces puedes hacer:
ev.getXLocation()
O algo así. Come butches.
fuente
Puede hacer una función de extensión en Kotlin, así:
fun View.setOnClickListenerWithPoint(action: (Point) -> Unit) { val coordinates = Point() val screenPosition = IntArray(2) setOnTouchListener { v, event -> if (event.action == MotionEvent.ACTION_DOWN) { v.getLocationOnScreen(screenPosition) coordinates.set(event.x.toInt() + screenPosition[0], event.y.toInt() + screenPosition[1]) } false } setOnClickListener { action.invoke(coordinates) } }
Si necesita un clic largo, simplemente reemplácelo
setOnClickListener
Lo uso
getLocationOnScreen()
porque necesito coordenadas para ViewHolder de RecyclerViewfuente