मल्टी-टच जेस्चर का मतलब है कि जब एक साथ कई पॉइंटर (उंगलियां) स्क्रीन पर टैप करें. इस दस्तावेज़ में, एक से ज़्यादा पॉइंटर वाले जेस्चर का पता लगाने का तरीका बताया गया है.
एक से ज़्यादा पॉइंटर ट्रैक करना
जब एक साथ कई पॉइंटर स्क्रीन पर टैप करते हैं, तो सिस्टम ये टच इवेंट जनरेट करता है:
ACTION_DOWN: sent when the first pointer taps the screen. इससे जेस्चर शुरू हो जाता है. इस पॉइंटर के लिए पॉइंटर डेटा,0में हमेशा इंडेक्स0पर होता है.MotionEventACTION_POINTER_DOWN: यह इवेंट तब भेजा जाता है, जब पहला पॉइंटर स्क्रीन पर आने के बाद कोई दूसरा पॉइंटर स्क्रीन पर आता है.getActionIndex()का इस्तेमाल करके, उस पॉइंटर का इंडेक्स पाया जा सकता है जो अभी-अभी नीचे गया है.ACTION_MOVE: यह इवेंट तब भेजा जाता है, जब किसी जेस्चर में बदलाव होता है. इसमें कितने भी पॉइंटर शामिल हो सकते हैं.ACTION_POINTER_UP: जब कोई नॉन-प्राइमरी पॉइंटर ऊपर जाता है, तब यह इवेंट ट्रिगर होता है.getActionIndex()का इस्तेमाल करके, उस पॉइंटर का इंडेक्स पाया जा सकता है जो अभी-अभी ऊपर गया है.ACTION_UP: यह इवेंट तब भेजा जाता है, जब आखिरी पॉइंटर स्क्रीन से हट जाता है.ACTION_CANCEL: इससे पता चलता है कि सभी पॉइंटर के साथ-साथ पूरे जेस्चर को रद्द कर दिया गया है.
शुरू और खत्म करने के लिए जेस्चर
जेस्चर, इवेंट की एक सीरीज़ होती है. यह ACTION_DOWN इवेंट से शुरू होती है और ACTION_UP या ACTION_CANCEL इवेंट पर खत्म होती है. एक समय में एक ही जेस्चर ऐक्टिव होता है. नीचे की ओर खींचने, घुमाने, ऊपर की ओर खींचने, और रद्द करने की कार्रवाइयां, पूरे जेस्चर पर लागू होती हैं. उदाहरण के लिए, ACTION_MOVE वाला कोई इवेंट, उस समय सभी पॉइंटर के नीचे की ओर जाने का संकेत दे सकता है.
पॉइंटर को ट्रैक करना
MotionEvent में अलग-अलग पॉइंटर की पोज़िशन को ट्रैक करने के लिए, पॉइंटर के इंडेक्स और आईडी का इस्तेमाल करें.
- इंडेक्स:
MotionEvent, पॉइंटर की जानकारी को ऐरे में सेव करता है. किसी पॉइंटर का इंडेक्स, इस ऐरे में उसकी पोज़िशन होती है.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 कार्रवाइयाँ वापस पाना
MotionEvent की कार्रवाई वापस पाने के लिए, getActionMasked() तरीके या कंपैटिबिलिटी वर्शन MotionEventCompat.getActionMasked() का इस्तेमाल करें. पहले के 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 ""; }
अन्य संसाधन
इनपुट इवेंट से जुड़ी ज़्यादा जानकारी के लिए, यहां दिए गए रेफ़रंस देखें:
- इनपुट इवेंट की खास जानकारी
- सेंसर की खास जानकारी
- कस्टम व्यू को इंटरैक्टिव बनाना
- खींचकर छोड़ना और स्केल करना