2011-09-16 19 views
17

मैं नहीं पूछ रहा हूं कि स्पर्श घटनाओं को कैसे संभाला जाए, लेकिन दृश्यों के पीछे क्या चल रहा है? यदि कई नेस्टेड विजेट हैं, तो वे किस क्रम में ईवेंट देखते हैं? क्या डेवलपर पर इसका कोई नियंत्रण है? आदर्श रूप में मैं इस विषय पर एक दस्तावेज़ चाहता हूं।एंड्रॉइड टच इवेंट कैसे वितरित किए जाते हैं?

उत्तर

21
गतिविधि दृष्टिकोण से

:

टच घटनाओं Activity.dispatchTouchEvent करने के लिए पहले दिया जाता है। यह वह जगह है जहां आप उन्हें पहले पकड़ सकते हैं।

यहां वे खिड़की पर भेज दिए जाते हैं, जहां वे दृश्य पदानुक्रम को पार करते हैं, इस तरह के क्रम में कि आखिरी बार खींचे गए विजेट (अन्य विगेट्स के शीर्ष पर) को पहले View.onTouchEvent में स्पर्श करने की संभावना है। अगर कुछ दृश्य टचवेन्ट में सत्य लौटाते हैं, तो ट्रैवर्सल स्टॉप और अन्य दृश्य स्पर्श ईवेंट प्राप्त नहीं करते हैं।

अंत में, यदि कोई दृश्य स्पर्श नहीं करता है, तो यह गतिविधि.ऑन टचवेन्ट को दिया जाता है।

यह आपका पूरा नियंत्रण है। और यह तर्कसंगत है कि जो कुछ आप किसी और चीज के शीर्ष पर खींचे जाते हैं, उसके पास नीचे खींची गई चीज़ से पहले टच इवेंट को संसाधित करने का मौका होता है।

+0

आप दस्तावेज़ इस का वर्णन करने का किसी भी तरह का है? – DJClayworth

+0

प्रेषण के बारे में: मैं स्रोत कोड और फ़ंक्शन टिप्पणियां पढ़ सकता हूं। व्यू ट्रैवर्सल के आदेश के बारे में - मैंने इसे कुछ दस्तावेज़ में पढ़ा है, निश्चित रूप से developer.android.com पर, लेकिन अब बिल्कुल नहीं बता सकता है। –

+0

वैसे भी, अच्छी शुरुआत: http://developer.android.com/guide/topics/ui/ui-events.html –

10

चलिए एक दृश्य उदाहरण देखें।

enter image description here

जब एक स्पर्श घटना होती है, पहले हर किसी को घटना के बारे में सूचित किया जाता है, गतिविधि से शुरू होकर शीर्ष पर देखने के लिए सभी तरह से जा रहा है। फिर सभी को घटना को संभालने का मौका दिया जाता है, शीर्ष पर देखने के साथ शुरू होता है और गतिविधि पर वापस जाता है। तो गतिविधि इसे सुनने वाला पहला व्यक्ति है और अंतिम इसे संभालने का मौका दिया जाता है।

enter image description here

गतिविधि या कुछ ViewGroup अभी स्पर्श घटना को संभालने के लिए चाहता है तो यह सिर्फ true लौट सकते हैं अपनी onInterceptTouchEvent() में (और न लाइन यह करने के अवसर के नीचे किसी और को दे)।

यदि कोई दृश्य (या व्यू ग्रुप) में OnTouchListener है, तो स्पर्श ईवेंट OnTouchListener.onTouch() द्वारा प्रबंधित किया जाता है। अन्यथा इसे onTouchEvent() द्वारा संभाला जाता है। यदि onTouchEvent() किसी भी टच ईवेंट के लिए true लौटाता है, तो हैंडलिंग वहां रुक जाती है। लाइन के नीचे कोई भी इस पर एक मौका नहीं मिलता है।

अधिक विस्तृत विवरण

ऊपर चित्र बातें थोड़ा और अधिक सरल वास्तविक की तुलना में आसान बनाता है। उदाहरण के लिए, गतिविधि और दृश्य समूह ए (रूट लेआउट) के बीच विंडो और सजावट दृश्य भी है। मैंने उन्हें ऊपर छोड़ दिया क्योंकि हमें आम तौर पर उनके साथ बातचीत करने की ज़रूरत नहीं है। हालांकि, मैं उन्हें नीचे शामिल करूँगा। नीचे दिया गया विवरण स्रोत कोड के माध्यम से एक स्पर्श घटना का पालन करता है। आप वास्तविक स्रोत कोड देखने के लिए एक लिंक पर क्लिक कर सकते हैं।

  1. गतिविधि की dispatchTouchEvent() एक स्पर्श घटना के बारे में अधिसूचित है। टच इवेंट MotionEvent के रूप में पारित किया गया है, जिसमें एक्स, वाई निर्देशांक, समय, घटना का प्रकार, और अन्य जानकारी शामिल है।
  2. स्पर्श ईवेंट विंडो के superDispatchTouchEvent() पर भेजा जाता है। Window एक अमूर्त वर्ग है। वास्तविक कार्यान्वयन PhoneWindow है।
  3. अधिसूचना प्राप्त करने के लिए अगली पंक्ति में सजावट दृश्य superDispatchTouchEvent() है।DecorView स्टेटस बार, नेविगेशन बार, सामग्री क्षेत्र इत्यादि को नियंत्रित करता है It is actually just a FrameLayout subclass, जो स्वयं ViewGroup का सबक्लास है।
  4. अधिसूचना प्राप्त करने वाला अगला व्यक्ति (यदि मैं गलत हूं तो मुझे सही करें) आपकी गतिविधि का सामग्री दृश्य है। जब आप एंड्रॉइड स्टूडियो के लेआउट एडिटर में लेआउट बनाते हैं तो आप एक्सएमएल में अपनी गतिविधि के मूल लेआउट के रूप में सेट करते हैं। तो क्या आप RelativeLayout, LinearLayout, या ConstraintLayout चुनते हैं, वे ViewGroup के सभी उप-वर्ग हैं। और व्यू ग्रुप को dispatchTouchEvent() में टच इवेंट की अधिसूचना मिलती है। यह उपरोक्त मेरे आरेखों में व्यू ग्रुप ए है।
  5. ViewGroupnotify any children में ViewGroup बच्चों सहित टच ईवेंट का होगा। उपरोक्त मेरे आरेखों में यह व्यू ग्रुप बी है।
  6. रास्ते में कहीं भी, ViewGroupshort-circuitonInterceptTouchEvent() के लिए true लौटाकर अधिसूचना प्रक्रिया कर सकता है।
  7. मानते हैं कि ViewGroup अधिसूचनाओं को कम करता है, अधिसूचनाओं के लिए रेखा का प्राकृतिक अंत तब होता है जब दृश्य का dispatchTouchEvent() मिलता है।
  8. अब समय है, घटनाओं को संभालने शुरू करने के लिए। If there is an OnTouchListener, तो यह onTouch() के साथ टच इवेंट को संभालने का पहला मौका मिलता है। Otherwise, दृश्य onTouchEvent() इसे संभालने के लिए मिलता है।
  9. अब सभी व्यू ग्रुप लाइन को बार-बार स्पर्श करते हैं, जिस तरह से View ने स्पर्श ईवेंट को संभालने का मौका दिया। हालांकि, मैंने उपरोक्त आरेख में यह इंगित नहीं किया है, ViewGroupView सबक्लास है, इसलिए मैंने जो कुछ भी वर्णन किया है, उसके बारे में OnTouchListener.onTouch() और onTouchEvent() भी ViewGroups पर लागू होता है।
  10. Finally, अगर कोई और इसे नहीं चाहता है, तो गतिविधि को onTouchEvent() के साथ ईवेंट को संभालने का आखिरी मौका भी मिलता है।

पूछे जाने वाले प्रश्न

जब मैं कभी dispatchTouchEvent() ओवरराइड करने के लिए की आवश्यकता होगी?

शायद आपको तब तक कुछ अतिरिक्त रूटिंग करने की आवश्यकता नहीं है जब तक कि डिफ़ॉल्ट रूप से ऐसा न हो। स्पर्श ईवेंट अधिसूचनाओं की निगरानी करने के लिए, आप इसके बजाय onInterceptTouchEvent() ओवरराइड कर सकते हैं।

मुझे कभी भी onInterceptTouchEvent() ओवरराइड करने की आवश्यकता कब होगी?

यदि आप बस आने वाली स्पर्श अधिसूचनाओं का जासूसी करना चाहते हैं, तो आप इसे यहां कर सकते हैं और false वापस कर सकते हैं।

हालांकि, इस विधि को ओवरराइड करने का मुख्य उद्देश्य दृश्य समूह को किसी अन्य प्रकार के स्पर्श ईवेंट को संभालने देना है जबकि बच्चे को किसी अन्य प्रकार को संभालने देना है। उदाहरण के लिए, ScrollView स्क्रॉलिंग को संभालने के लिए यह करता है जबकि अपने बच्चे को बटन क्लिक की तरह कुछ संभालने देता है। इसके विपरीत, यदि बच्चा दृश्य अपने माता-पिता को अपनी स्पर्श घटना चुरा नहीं देना चाहता, तो यह requestDisallowTouchIntercept() पर कॉल कर सकता है।

टच इवेंट प्रकार क्या हैं?

वाले मुख्य

  • ACTION_DOWN कर रहे हैं - यह एक स्पर्श घटना की शुरुआत है। यदि आप टच इवेंट को संभालना चाहते हैं तो onTouchEvent में ACTION_DOWN ईवेंट के लिए आपको हमेशा true वापस करना चाहिए। अन्यथा, आपको कोई और घटनाएं नहीं मिलेंगी।
  • ACTION_MOVE - जब आप अपनी उंगली को स्क्रीन पर ले जाते हैं तो यह घटना लगातार निकाल दी जाती है।
  • ACTION_UP - यह एक स्पर्श कार्यक्रम की आखिरी घटना है।

एक धावक ACTION_CANCEL है। यह कहा जाता है कि पेड़ पर एक व्यू ग्रुप टच इवेंट को रोकने का फैसला करता है।

आप अन्य प्रकार के मोशनवेन्ट्स here देख सकते हैं। चूंकि एंड्रॉइड मल्टी-टच है, इसलिए अन्य उंगलियों ("पॉइंटर्स") स्क्रीन को स्पर्श करते समय ईवेंट भी निकाल दिए जाते हैं।

आगे के अध्ययन के

संबंधित मुद्दे