Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym temacie pokazano, jak śledzić zdarzenia dotykowe z wielu palców
Czasami aplikacja wielodotykowa musi śledzić poszczególne palce, gdy poruszają się jednocześnie na ekranie. Jedną z typowych aplikacji jest program malowania palcami. Chcesz, aby użytkownik mógł rysować za pomocą pojedynczego palca, ale także rysować z wieloma palcami jednocześnie. Ponieważ program przetwarza wiele zdarzeń dotykowych, musi odróżnić zdarzenia odpowiadające każdemu palcem. W tym celu system Android dostarcza kod identyfikatora, ale uzyskanie i obsługa tego kodu może być nieco trudne.
Dla wszystkich zdarzeń skojarzonych z określonym palcem kod identyfikatora pozostaje taki sam. Kod identyfikatora jest przypisywany, gdy palec po raz pierwszy dotyka ekranu i staje się nieprawidłowy po naciśnięciu palca z ekranu. Te kody identyfikatorów są zazwyczaj bardzo małymi liczbami całkowitymi, a system Android ponownie używa ich w przypadku późniejszych zdarzeń dotykowych.
Prawie zawsze, program, który śledzi poszczególne palce utrzymuje słownik do śledzenia dotyku. Klucz słownika to kod identyfikatora, który identyfikuje konkretny palec. Wartość słownika zależy od aplikacji. W przykładzie FingerPaint każdy pociągnięcie palca (od dotyku do zwolnienia) jest skojarzone z obiektem zawierającym wszystkie informacje niezbędne do renderowania linii narysowanej palcem. Program definiuje małą FingerPaintPolyline klasę w tym celu:
class FingerPaintPolyline
{
public FingerPaintPolyline()
{
Path = new Path();
}
public Color Color { set; get; }
public float StrokeWidth { set; get; }
public Path Path { private set; get; }
}
Każda wielolinia ma kolor, szerokość pociągnięcia i obiekt graficzny systemu Path Android do gromadzenia i renderowania wielu punktów linii podczas rysowania.
Pozostała część kodu pokazanego poniżej znajduje się w pochodnej View nazwie FingerPaintCanvasView. Ta klasa utrzymuje słownik obiektów typu FingerPaintPolyline w czasie, gdy są aktywnie rysowane przez co najmniej jeden palec:
Dictionary<int, FingerPaintPolyline> inProgressPolylines = new Dictionary<int, FingerPaintPolyline>();
Ten słownik umożliwia szybkie uzyskanie FingerPaintPolyline informacji skojarzonych z konkretnym palcem.
Klasa FingerPaintCanvasView obsługuje List również obiekt dla linii polilinii, które zostały ukończone:
List<FingerPaintPolyline> completedPolylines = new List<FingerPaintPolyline>();
Obiekty w tej List kolejności znajdują się w tej samej kolejności, w której zostały narysowane.
FingerPaintCanvasView zastępuje dwie metody zdefiniowane przez View: OnDraw i OnTouchEvent.
W jego OnDraw przesłonięć widok rysuje ukończone linie wieloliniowe, a następnie rysuje wielolinie w toku.
Zastąpienie OnTouchEvent metody rozpoczyna się od uzyskania pointerIndex wartości z ActionIndex właściwości . Ta ActionIndex wartość rozróżnia wiele palców, ale nie jest spójna w wielu zdarzeniach. Z tego powodu użyj polecenia , pointerIndex aby uzyskać wartość wskaźnika id z GetPointerId metody . Ten identyfikator jest spójny w wielu zdarzeniach:
public override bool OnTouchEvent(MotionEvent args)
{
// Get the pointer index
int pointerIndex = args.ActionIndex;
// Get the id to identify a finger over the course of its progress
int id = args.GetPointerId(pointerIndex);
// Use ActionMasked here rather than Action to reduce the number of possibilities
switch (args.ActionMasked)
{
// ...
}
// Invalidate to update the view
Invalidate();
// Request continued touch input
return true;
}
Zwróć uwagę, że przesłonięcia używają ActionMasked właściwości w instrukcji switch , a nie Action właściwości . Poniżej przedstawiono przyczyny:
Gdy masz do czynienia z wieloma dotykami, Action właściwość ma wartość MotionEventsAction.Down dla pierwszego palca, aby dotknąć ekranu, a następnie wartości Pointer2Down i Pointer3Down jako drugie i trzecie palce również dotknąć ekranu. Jako czwarte i piąte palce nawiązać kontakt, Action właściwość ma wartości liczbowe, które nawet nie odpowiadają członkom MotionEventsAction wyliczenia! Należy zbadać wartości flag bitowych w wartościach, aby zinterpretować, co oznaczają.
Podobnie, jak palce pozostawiają kontakt z ekranem, Action właściwość ma wartości Pointer2Up i Pointer3Up dla drugiego i trzeciego palca, a Up dla pierwszego palca.
Właściwość ActionMasked przyjmuje mniejszą liczbę wartości, ponieważ ma być używana w połączeniu z właściwością ActionIndex , aby odróżnić wiele palców. Gdy palce dotykają ekranu, właściwość może być równa MotionEventActions.Down tylko dla pierwszego palca i PointerDown kolejnych palców. Gdy palce opuszczają ekran, ActionMasked ma wartości Pointer1Up dla kolejnych palców i Up pierwszego palca.
W przypadku używania ActionMaskedparametru ActionIndex wyróżnia się między kolejnymi palcami, aby dotknąć i opuścić ekran, ale zwykle nie trzeba używać tej wartości, z wyjątkiem argumentu dla innych metod w MotionEvent obiekcie. W przypadku wielodotyku jedna z najważniejszych z tych metod jest GetPointerId wywoływana w powyższym kodzie. Ta metoda zwraca wartość, której można użyć dla klucza słownika, aby skojarzyć określone zdarzenia z palcami.
Przesłonięcia OnTouchEvent w przykładzie przetwarza zdarzenia MotionEventActions.Down i PointerDown identycznie, tworząc nowy FingerPaintPolyline obiekt i dodając go do słownika:
public override bool OnTouchEvent(MotionEvent args)
{
// Get the pointer index
int pointerIndex = args.ActionIndex;
// Get the id to identify a finger over the course of its progress
int id = args.GetPointerId(pointerIndex);
// Use ActionMasked here rather than Action to reduce the number of possibilities
switch (args.ActionMasked)
{
case MotionEventActions.Down:
case MotionEventActions.PointerDown:
// Create a Polyline, set the initial point, and store it
FingerPaintPolyline polyline = new FingerPaintPolyline
{
Color = StrokeColor,
StrokeWidth = StrokeWidth
};
polyline.Path.MoveTo(args.GetX(pointerIndex),
args.GetY(pointerIndex));
inProgressPolylines.Add(id, polyline);
break;
// ...
}
// ...
}
Zwróć uwagę, że pointerIndex element jest również używany do uzyskania położenia palca w widoku. Wszystkie informacje dotykowe są skojarzone z wartością pointerIndex . Element id jednoznacznie identyfikuje palce w wielu komunikatach, dzięki czemu jest używany do tworzenia wpisu słownika.
OnTouchEvent Podobnie przesłonięcia obsługują również metodę MotionEventActions.Up i Pointer1Up identycznie, przenosząc ukończoną wielolinię do completedPolylines kolekcji, aby można je było narysować podczas OnDraw przesłonięcia. Kod usuwa id również wpis ze słownika:
public override bool OnTouchEvent(MotionEvent args)
{
// ...
switch (args.ActionMasked)
{
// ...
case MotionEventActions.Up:
case MotionEventActions.Pointer1Up:
inProgressPolylines[id].Path.LineTo(args.GetX(pointerIndex),
args.GetY(pointerIndex));
// Transfer the in-progress polyline to a completed polyline
completedPolylines.Add(inProgressPolylines[id]);
inProgressPolylines.Remove(id);
break;
case MotionEventActions.Cancel:
inProgressPolylines.Remove(id);
break;
}
// ...
}
Teraz na trudną część.
Między zdarzeniami w dół i w górę zazwyczaj istnieje wiele MotionEventActions.Move zdarzeń. Są one umieszczane w jednym wywołaniu metody OnTouchEventi muszą być obsługiwane inaczej niż zdarzenia Down i Up . Wartość pointerIndex uzyskana wcześniej z ActionIndex właściwości musi być ignorowana. Zamiast tego metoda musi uzyskać wiele pointerIndex wartości przez pętlę z zakresu od 0 do PointerCount właściwości, a następnie uzyskać dla id każdej z tych pointerIndex wartości:
public override bool OnTouchEvent(MotionEvent args)
{
// ...
switch (args.ActionMasked)
{
// ...
case MotionEventActions.Move:
// Multiple Move events are bundled, so handle them differently
for (pointerIndex = 0; pointerIndex < args.PointerCount; pointerIndex++)
{
id = args.GetPointerId(pointerIndex);
inProgressPolylines[id].Path.LineTo(args.GetX(pointerIndex),
args.GetY(pointerIndex));
}
break;
// ...
}
// ...
}
Ten typ przetwarzania umożliwia przykładowi śledzenie poszczególnych palców i rysowanie wyników na ekranie:
Wiesz już, jak można śledzić poszczególne palce na ekranie i rozróżniać je.