Eu tenho uma visão customizada derivada de View. Gostaria de ser notificado quando a visualização for clicada e o local x, y de onde o clique aconteceu. O mesmo para cliques longos.
Parece que vou fazer isso, preciso substituir onTouchEvent()
. Mas não há como obter a localização x, y do evento de um OnClickListener
?
Se não, qual é uma boa maneira de saber se um evento de movimento é um clique 'real' versus um clique longo etc? O onTouchEvent
gera muitos eventos em rápida sucessão etc.
false
para não bloquear eventos de toque? (View.OnTouchListener.onTouch retorna verdadeiro se o ouvinte consumiu o evento, caso contrário, falso.)OnClickListener
é disparado quando o dedo é liberado, portanto,ACTION_UP
mas com limitações: se o gesto de atirar (deslizar) foi executado,OnClickListener
não é disparado, masACTION_UP
ainda será processado.(event.getX(), event.getY())
mas não está escrevendo na posição correta.Exemplo completo
As outras respostas estão faltando alguns detalhes. Aqui está um exemplo 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); } }; }
Resumo
OnTouchListener
OnClickListener
fonte
Substituir onTouchEvent (MotionEvent ev)
Então você pode fazer:
ev.getXLocation()
Ou algo assim. Tenha um butches.
fonte
Você pode fazer uma função de extensão em Kotlin, assim:
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) } }
Se você precisar de um clique longo - basta substituir
setOnClickListener
Eu uso
getLocationOnScreen()
porque preciso de coordenadas para ViewHolder do RecyclerViewfonte