Jak uzyskać pozycję Touch w Androidzie?

92

Muszę uzyskać dotknięcie pozycji początkowej (X, Y), dotknięcia pozycji przesunięcia i dotknięcia pozycji końcowej ekranu w Androidzie.

Alex
źródło

Odpowiedzi:

170
@Override
public boolean onTouchEvent(MotionEvent event)
{
    int x = (int)event.getX();
    int y = (int)event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_MOVE:
        case MotionEvent.ACTION_UP:
    }

    return false;
}

Te trzy przypadki są po to, abyś mógł reagować na różne typy zdarzeń, w tym przykładzie ponownie dotykając, przeciągając lub podnosząc palec.

dbrettschneider
źródło
7
Dlaczego zwracasz fałsz?
Daniel Reyhanian,
1
Zwrócona wartość true oznaczałaby, że zdarzenie dotyku zostało obsłużone, co uniemożliwiłoby jego propagację i odwrotnie.
chaosifier
27

Dodatkowa odpowiedź

Biorąc pod uwagę OnTouchListener

private View.OnTouchListener handleTouch = new View.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        int x = (int) event.getX();
        int y = (int) event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.i("TAG", "touched down");
                break;
            case MotionEvent.ACTION_MOVE:
                Log.i("TAG", "moving: (" + x + ", " + y + ")");
                break;
            case MotionEvent.ACTION_UP:
                Log.i("TAG", "touched up");
                break;
        }

        return true;
    }
};

ustawione na jakiś widok:

myView.setOnTouchListener(handleTouch);

Zapewnia to współrzędne zdarzenia dotyku względem widoku, do którego jest przypisany odbiornik dotyku. W lewym górnym rogu widoku jest (0, 0). Jeśli przesuniesz palcem nad widok, ybędzie ujemny. Jeśli przesuniesz palcem w lewo od widoku, xbędzie to wartość ujemna.

int x = (int)event.getX();
int y = (int)event.getY();

Jeśli chcesz mieć współrzędne względem lewego górnego rogu ekranu urządzenia, użyj surowych wartości.

int x = (int)event.getRawX();
int y = (int)event.getRawY();

Związane z

Suragch
źródło
To działa, jednak w moich testach widok, do którego jest dodawany słuchacz, nie powinien być zasłaniany przez inne widoki. Aby uzyskać absolutne współrzędne dotkniętej pozycji na ekranie, dodałem układ ramek jako widok bazowy, a na górze widok ze słuchaczem. Nie zapomnij, w return falseprzeciwnym razie pochłonie dotyk.
lenooh
@lenooh, getRawX()i getRawY()powinien zwrócić bezwzględne współrzędne pozycji dotyku w każdym widoku, do którego jest dodawany słuchacz. Ale masz rację, jeśli na wierzchu jest inny widok, który powracatrue , żadne dolne widoki nie będą powiadamiane o zdarzeniach dotykowych.
Suragch,
Suragch: dokładnie. Ponieważ używam FrameLayout, ustawiłem widok na „matchParent”, więcgetX() i getY()działać dobrze (nie ma potrzeby getRawX/Y()).
lenooh
@Suragch Czy w ogóle istnieje możliwość nagrywania dotyku, nawet jeśli jest on zasłonięty innym widokiem lub ma dzieci lubią przyciski?
vignesh kumar
@vigneshkumar, widoki są powiadamiane o zdarzeniach dotykowych od dołu do góry (patrz link na dole mojej odpowiedzi), więc możesz nagrać zdarzenie, onInterceptTouchEventa następnie wrócić, falseaby zdarzenie było przetwarzane normalnie.
Suragch
10
@Override
    public boolean onTouch(View v, MotionEvent event) {
       float x = event.getX();
       float y = event.getY();
       return true;
    }
Sephy
źródło
0

Oto styl Koltin, używam tego w swoim projekcie i działa bardzo dobrze:

this.yourview.setOnTouchListener(View.OnTouchListener { _, event ->
        val x = event.x
        val y = event.y

        when(event.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d(TAG, "ACTION_DOWN \nx: $x\ny: $y")
            }
            MotionEvent.ACTION_MOVE -> {
                Log.d(TAG, "ACTION_MOVE \nx: $x\ny: $y")
            }
            MotionEvent.ACTION_UP -> {
                Log.d(TAG, "ACTION_UP \nx: $x\ny: $y")
            }
        }
        return@OnTouchListener  true
    })
cjung
źródło