תנועה מרובת מגע היא תנועה שבה כמה מצביעים (אצבעות) מקישים על המסך בו-זמנית. במסמך הזה מוסבר איך לזהות תנועות שכוללות כמה מצביעים.
מעקב אחרי כמה מצביעים
כשכמה מצביעים מקישים על המסך בו-זמנית, המערכת יוצרת את אירועי המגע הבאים:
-
ACTION_DOWN: נשלח כשהמצביע הראשון מקיש על המסך. כך מתחילים את התנועה. נתוני המצביע הזה תמיד נמצאים באינדקס0ב-MotionEvent. -
ACTION_POINTER_DOWN: נשלח כשסמנים נוספים נכנסים למסך אחרי הראשון. אפשר לקבל את האינדקס של מצביע העכבר שפשוט ירד באמצעותgetActionIndex(). -
ACTION_MOVE: נשלח כשמתרחש שינוי בתנועה, שכולל מספר כלשהו של נקודות מיקום. -
ACTION_POINTER_UP: נשלח כשמצביע לא ראשי עולה. אפשר לקבל את האינדקס של מצביע שעלה באמצעותgetActionIndex(). ACTION_UP: נשלח כשהסמן האחרון עוזב את המסך.-
ACTION_CANCEL: מציין שכל התנועה, כולל כל הסמנים, בוטלה.
מחוות התחלה וסיום
מחווה היא סדרה של אירועים שמתחילה באירוע ACTION_DOWN ומסתיימת באירוע ACTION_UP או באירוע ACTION_CANCEL. רק תנועה אחת יכולה להיות פעילה בכל פעם. הפעולות DOWN, MOVE, UP ו-CANCEL חלות על כל תנועת היד. לדוגמה, אירוע עם ACTION_MOVE יכול לציין תנועה של כל המצביעים למטה באותו רגע.
מעקב אחרי מצביעים
כדי לעקוב אחרי המיקומים של הסמנים בתוך MotionEvent, משתמשים באינדקס ובמזהה של הסמן.
- אינדקס: מצביע
MotionEventstores למידע במערך. האינדקס של מצביע הוא המיקום שלו במערך הזה. רוב השיטות שלMotionEventמקבלות את אינדקס המצביע כפרמטר, ולא את מזהה המצביע. - מזהה: לכל מצביע יש גם מיפוי מזהה שנשאר קבוע לאורך אירועי מגע, כדי לאפשר מעקב אחרי מצביע ספציפי לאורך כל תנועת היד.
מצביעים בודדים מופיעים באירוע תנועה בסדר לא מוגדר. לכן, האינדקס של מצביע יכול להשתנות מאירוע אחד למשנהו, אבל מובטח שמזהה המצביע יישאר קבוע כל עוד המצביע פעיל. משתמשים בשיטה
getPointerId()
כדי לקבל מזהה של מצביע למעקב אחרי המצביע בכל אירועי התנועה הבאים במחווה. לאחר מכן, לאירועי תנועה עוקבים, משתמשים בשיטה findPointerIndex() כדי לקבל את אינדקס מצביע העכבר עבור מזהה מצביע נתון באירוע התנועה הזה.
לדוגמה:
Kotlin
private var mActivePointerId: Int = 0 override fun onTouchEvent(event: MotionEvent): Boolean { ... // Get the pointer ID. mActivePointerId = event.getPointerId(0) // ... Many touch events later... // Use the pointer ID to find the index of the active pointer // and fetch its position. val (x: Float, y: Float) = event.findPointerIndex(mActivePointerId).let { pointerIndex -> // Get the pointer's current position. event.getX(pointerIndex) to event.getY(pointerIndex) } ... }
Java
private int mActivePointerId; public boolean onTouchEvent(MotionEvent event) { ... // Get the pointer ID. mActivePointerId = event.getPointerId(0); // ... Many touch events later... // Use the pointer ID to find the index of the active pointer // and fetch its position. int pointerIndex = event.findPointerIndex(mActivePointerId); // Get the pointer's current position. float x = event.getX(pointerIndex); float y = event.getY(pointerIndex); ... }
כדי לתמוך בכמה סמני מיקום של מגע, אפשר לשמור במטמון את כל הסמנים הפעילים עם המזהים שלהם בזמן האירוע של ACTION_POINTER_DOWN ושל ACTION_DOWN. מסירים את המצביעים מהמטמון באירועים ACTION_POINTER_UP וACTION_UP. יכול להיות שהמזהים האלה שנשמרו במטמון יעזרו לכם לטפל באירועים אחרים של פעולות בצורה נכונה. לדוגמה, כשמעבדים אירוע ACTION_MOVE, מוצאים את האינדקס של כל מזהה מצביע פעיל שנשמר במטמון, מאחזרים את הקואורדינטות של המצביע באמצעות הפונקציות getX() ו-getY(), ואז משווים את הקואורדינטות האלה לקואורדינטות שנשמרו במטמון כדי לגלות אילו מצביעים זזו.
אפשר להשתמש בפונקציה getActionIndex() רק עם אירועים מסוג ACTION_POINTER_UP ו-ACTION_POINTER_DOWN. אין להשתמש בפונקציה הזו עם אירועים מסוג ACTION_MOVE, כי היא תמיד מחזירה 0.
אחזור MotionEvent פעולות
אפשר להשתמש בשיטה getActionMasked() או בגרסת התאימות MotionEventCompat.getActionMasked() כדי לאחזר את הפעולה של MotionEvent. בניגוד לשיטה הקודמת, getAction() נועדה לעבוד עם כמה מצביעים.getActionMasked() הפונקציה מחזירה את הפעולה בלי אינדקסים של מצביעים. לפעולות עם אינדקס מצביע תקף, משתמשים ב-getActionIndex() כדי להחזיר את האינדקס של המצביעים שמשויכים לפעולה, כמו שמוצג בקטע הקוד הבא:
Kotlin
val (xPos: Int, yPos: Int) = MotionEventCompat.getActionMasked(event).let { action -> Log.d(DEBUG_TAG, "The action is ${actionToString(action)}") // Get the index of the pointer associated with the action. MotionEventCompat.getActionIndex(event).let { index -> // The coordinates of the current screen contact, relative to // the responding View or Activity. MotionEventCompat.getX(event, index).toInt() to MotionEventCompat.getY(event, index).toInt() } } if (event.pointerCount > 1) { Log.d(DEBUG_TAG, "Multitouch event") } else { // Single touch event. Log.d(DEBUG_TAG, "Single touch event") } ... // Given an action int, returns a string description. fun actionToString(action: Int): String { return when (action) { MotionEvent.ACTION_DOWN -> "Down" MotionEvent.ACTION_MOVE -> "Move" MotionEvent.ACTION_POINTER_DOWN -> "Pointer Down" MotionEvent.ACTION_UP -> "Up" MotionEvent.ACTION_POINTER_UP -> "Pointer Up" MotionEvent.ACTION_OUTSIDE -> "Outside" MotionEvent.ACTION_CANCEL -> "Cancel" else -> "" } }
Java
int action = MotionEventCompat.getActionMasked(event); // Get the index of the pointer associated with the action. int index = MotionEventCompat.getActionIndex(event); int xPos = -1; int yPos = -1; Log.d(DEBUG_TAG,"The action is " + actionToString(action)); if (event.getPointerCount() > 1) { Log.d(DEBUG_TAG,"Multitouch event"); // The coordinates of the current screen contact, relative to // the responding View or Activity. xPos = (int)MotionEventCompat.getX(event, index); yPos = (int)MotionEventCompat.getY(event, index); } else { // Single touch event. Log.d(DEBUG_TAG,"Single touch event"); xPos = (int)MotionEventCompat.getX(event, index); yPos = (int)MotionEventCompat.getY(event, index); } ... // Given an action int, returns a string description public static String actionToString(int action) { switch (action) { case MotionEvent.ACTION_DOWN: return "Down"; case MotionEvent.ACTION_MOVE: return "Move"; case MotionEvent.ACTION_POINTER_DOWN: return "Pointer Down"; case MotionEvent.ACTION_UP: return "Up"; case MotionEvent.ACTION_POINTER_UP: return "Pointer Up"; case MotionEvent.ACTION_OUTSIDE: return "Outside"; case MotionEvent.ACTION_CANCEL: return "Cancel"; } return ""; }
מקורות מידע נוספים
מידע נוסף על אירועי קלט זמין במקורות המידע הבאים:
- סקירה כללית של אירועי קלט
- סקירה כללית בנושא חיישנים
- איך יוצרים תצוגה אינטראקטיבית בהתאמה אישית
- גרירה ושינוי גודל