ท่าทางสัมผัสแบบมัลติทัชคือการที่พอยน์เตอร์ (นิ้ว) หลายตัวแตะหน้าจอพร้อมกัน เอกสารนี้อธิบายวิธีตรวจหาท่าทางสัมผัสที่เกี่ยวข้องกับ เคอร์เซอร์หลายตัว
ติดตามเคอร์เซอร์หลายตัว
เมื่อพอยน์เตอร์หลายตัวแตะหน้าจอพร้อมกัน ระบบจะสร้างเหตุการณ์การแตะต่อไปนี้
ACTION_DOWN: ส่งเมื่อพอยน์เตอร์แรกแตะหน้าจอ ซึ่งจะเป็นการเริ่มท่าทางสัมผัส ข้อมูลเคอร์เซอร์สำหรับเคอร์เซอร์นี้จะอยู่ที่ดัชนี0ในMotionEventเสมอACTION_POINTER_DOWN: ส่งเมื่อเคอร์เซอร์เพิ่มเติมเข้าสู่หน้าจอหลังจากเคอร์เซอร์แรก คุณรับดัชนีของพอยน์เตอร์ที่เพิ่งลงได้โดยใช้getActionIndex()ACTION_MOVE: ส่งเมื่อมีการเปลี่ยนแปลงท่าทางสัมผัสที่เกี่ยวข้องกับพอยน์เตอร์ จำนวนเท่าใดก็ได้ACTION_POINTER_UP: ส่งเมื่อพอยน์เตอร์ที่ไม่ใช่พอยน์เตอร์หลักขึ้น คุณสามารถรับดัชนีของ พอยน์เตอร์ที่เพิ่งขึ้นมาได้โดยใช้getActionIndex()ACTION_UP: ส่งเมื่อเคอร์เซอร์สุดท้ายออกจากหน้าจอACTION_CANCEL: ระบุว่าท่าทางสัมผัสทั้งหมดรวมถึงเคอร์เซอร์ทั้งหมดถูกยกเลิก
ท่าทางสัมผัสเริ่มต้นและสิ้นสุด
ท่าทางสัมผัสคือชุดเหตุการณ์ที่เริ่มต้นด้วยเหตุการณ์ ACTION_DOWN
และสิ้นสุดด้วยเหตุการณ์ ACTION_UP หรือ
ACTION_CANCEL โดยจะใช้ท่าทางสัมผัสได้ครั้งละ 1 ท่า การดำเนินการ
DOWN, MOVE, UP และ CANCEL จะมีผลกับท่าทางสัมผัสทั้งหมด ตัวอย่างเช่น เหตุการณ์ที่มี ACTION_MOVE อาจบ่งบอกถึงการเคลื่อนไหวสำหรับตัวชี้ทั้งหมด
ลงในขณะนั้น
ติดตามพอยน์เตอร์
ใช้ดัชนีและรหัสของพอยน์เตอร์เพื่อติดตามตำแหน่งของพอยน์เตอร์แต่ละรายการภายใน MotionEvent
- ดัชนี: ข้อมูล
MotionEventตัวชี้ร้านค้า ในอาร์เรย์ ดัชนีของพอยน์เตอร์คือตำแหน่งภายในอาร์เรย์นี้ เมธอดMotionEventส่วนใหญ่ใช้ดัชนี Pointer เป็นพารามิเตอร์ แทนที่จะใช้รหัสพอยน์เตอร์ - รหัส: พอยน์เตอร์แต่ละรายการยังมีการแมปรหัสที่คงอยู่ ในเหตุการณ์การแตะเพื่อให้ติดตามพอยน์เตอร์แต่ละรายการ ในท่าทางสัมผัสทั้งหมดได้
เคอร์เซอร์แต่ละตัวจะปรากฏภายในเหตุการณ์การเคลื่อนไหวโดยไม่มีลำดับที่กำหนด ดังนั้น
ดัชนีของเคอร์เซอร์อาจเปลี่ยนจากเหตุการณ์หนึ่งไปยังเหตุการณ์ถัดไป แต่ระบบรับประกันว่ารหัสเคอร์เซอร์
ของเคอร์เซอร์จะยังคงเดิมตราบใดที่เคอร์เซอร์ยังคง
ใช้งานอยู่ ใช้เมธอด
getPointerId()
เพื่อรับรหัสของพอยน์เตอร์เพื่อติดตามพอยน์เตอร์ในเหตุการณ์การเคลื่อนไหว
ทั้งหมดที่ตามมาในท่าทางสัมผัส จากนั้นสําหรับเหตุการณ์การเคลื่อนไหวที่ต่อเนื่อง ให้ใช้เมธอด
findPointerIndex()
เพื่อรับดัชนี Pointer สําหรับรหัสพอยน์เตอร์ที่กําหนดในเหตุการณ์การเคลื่อนไหวนั้น
เช่น
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 getActionMasked() ออกแบบมาให้ทำงานร่วมกับพอยน์เตอร์หลายตัว ซึ่งต่างจากวิธีgetAction()
ก่อนหน้านี้
โดยจะแสดงผลการดำเนินการโดยไม่มีดัชนีพอยน์เตอร์ สำหรับการดำเนินการที่มีดัชนี Pointer ที่ถูกต้อง ให้ใช้ getActionIndex() เพื่อแสดงดัชนีของ Pointer ที่เชื่อมโยงกับการดำเนินการตามที่แสดงในข้อมูลโค้ดต่อไปนี้
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 ""; }
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับเหตุการณ์อินพุตได้ที่ข้อมูลอ้างอิงต่อไปนี้