Mam niestandardowy widok pochodzący z widoku. Chcę otrzymywać powiadomienia o kliknięciu widoku oraz o miejscu x, y miejsca kliknięcia. To samo dotyczy długich kliknięć.
Wygląda na to, że muszę to zrobić, muszę zmienić onTouchEvent()
. Czy OnClickListener
zamiast tego nie ma sposobu, aby uzyskać lokalizację x, y zdarzenia z an ?
Jeśli nie, jaki jest dobry sposób na stwierdzenie, czy zdarzenie ruchu jest „prawdziwym” kliknięciem, czy długim kliknięciem itp.? onTouchEvent
Generuje wiele wydarzeń w krótkim odstępie czasu itd.
false
aby nie blokował zdarzeń dotykowych? (View.OnTouchListener.onTouch zwraca wartość true, jeśli odbiornik wykorzystał zdarzenie, w przeciwnym razie false).OnClickListener
jest uruchamiany po zwolnieniu palca, więc w tym przypadku,ACTION_UP
ale z ograniczeniami: jeśli wykonano gest machnięcia (machnięcia),OnClickListener
to nie jest uruchamiany, aleACTION_UP
nadal będzie przetwarzany.(event.getX(), event.getY())
ale nie jest to pismo we właściwej pozycji.Pełny przykład
W innych odpowiedziach brakuje niektórych szczegółów. Oto pełny przykład.
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); } }; }
Podsumowanie
OnTouchListener
OnClickListener
źródło
Zastąp onTouchEvent (MotionEvent ev)
Następnie możesz:
ev.getXLocation()
Czy coś takiego. Miej pupy.
źródło
Możesz utworzyć funkcję rozszerzenia w Kotlinie, na przykład:
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) } }
Jeśli potrzebujesz długiego kliknięcia - po prostu wymień
setOnClickListener
Używam,
getLocationOnScreen()
ponieważ potrzebuję współrzędnych dla ViewHolder RecyclerViewźródło