इन सेक्शन में, खींचकर छोड़ने की प्रोसेस के कुछ मुख्य कॉन्सेप्ट के बारे में बताया गया है.
खींचें और छोड़ें सुविधा
'खींचें और छोड़ें' प्रोसेस में चार चरण या स्थितियां होती हैं: शुरू की गई, जारी है, छोड़ी गई, और खत्म हो गई.
- शुरू किया गया
उपयोगकर्ता के खींचने के जेस्चर के जवाब में, आपका ऐप्लिकेशन
startDragAndDrop()
को कॉल करता है, ताकि सिस्टम को खींचने और छोड़ने की कार्रवाई शुरू करने के लिए कहा जा सके. विधेय के आर्ग्युमेंट से ये चीज़ें मिलती हैं:- जिस डेटा को खींचा और छोड़ा जाना है.
- खींचकर छोड़ने पर दिखने वाली परछाई को ड्रॉ करने के लिए कॉलबैक
- खींचे गए डेटा के बारे में बताने वाला मेटाडेटा
- सिस्टम, ड्रैग शैडो पाने के लिए आपके ऐप्लिकेशन को कॉल करके जवाब देता है. इसके बाद, सिस्टम डिवाइस पर ड्रैग शैडो दिखाता है.
- इसके बाद, सिस्टम मौजूदा लेआउट में मौजूद सभी
View
ऑब्जेक्ट के ड्रैग इवेंट के लिसनर को, ऐक्शन टाइपACTION_DRAG_STARTED
वाला ड्रैग इवेंट भेजता है. ड्रैग इवेंट लिसनर कोtrue
दिखाना होगा, ताकि ड्रैग इवेंट और ड्रॉप इवेंट की सूचना मिलती रहे. इससे लिसनर को सिस्टम के साथ रजिस्टर किया जाता है. सिर्फ़ रजिस्टर किए गए लिसनर को ही ड्रैग इवेंट मिलते रहेंगे. इस दौरान, दर्शक अपने ड्रॉप टारगेटView
ऑब्जेक्ट के दिखने का तरीका भी बदल सकते हैं, ताकि यह दिखाया जा सके कि व्यू में ड्रॉप इवेंट स्वीकार किया जा सकता है. - अगर ड्रैग इवेंट के लिसनर से
false
मिलता है, तो मौजूदा कार्रवाई के लिए उसे ड्रैग इवेंट तब तक नहीं मिलते, जब तक सिस्टम कार्रवाई टाइपACTION_DRAG_ENDED
के साथ ड्रैग इवेंट नहीं भेजता.false
दिखाकर, listener, सिस्टम को बताता है कि उसे खींचकर छोड़ने की सुविधा में दिलचस्पी नहीं है और वह खींचे गए डेटा को स्वीकार नहीं करना चाहता.
- प्रोसेस जारी है
- उपयोगकर्ता, आइटम को खींचकर छोड़ता है. जब ड्रैग शैडो, ड्रॉप टारगेट के बाउंडिंग बॉक्स से इंटरसेक्शन करता है, तो सिस्टम टारगेट के ड्रैग इवेंट लिसनर को एक या उससे ज़्यादा ड्रैग इवेंट भेजता है. इवेंट के जवाब में, लिसनर ड्रॉप टारगेट
View
के दिखने के तरीके में बदलाव कर सकता है. उदाहरण के लिए, अगर इवेंट से पता चलता है कि ड्रैग किया गया शैडो, ड्रॉप टारगेट के बाउंडिंग बॉक्स में जा रहा है—कार्रवाई का टाइपACTION_DRAG_ENTERED
—तो दर्शकView
को हाइलाइट करके प्रतिक्रिया दे सकता है. - प्रेषित
- उपयोगकर्ता, ड्रॉप टारगेट के बाउंडिंग बॉक्स में, खींचे गए आइटम को छोड़ देता है. सिस्टम, ड्रॉप टारगेट के लिसनर को ऐक्शन टाइप
ACTION_DROP
वाला ड्रैग इवेंट भेजता है. ड्रैग इवेंट ऑब्जेक्ट में वह डेटा होता है जोstartDragAndDrop()
को कॉल करने पर सिस्टम को भेजा जाता है. इससे ऑपरेशन शुरू होता है. अगर listener, ड्रॉप किए गए डेटा को सही तरीके से प्रोसेस करता है, तो उसे सिस्टम को बूलियनtrue
दिखाना चाहिए. : यह चरण सिर्फ़ तब होता है, जब उपयोगकर्ता खींचे गए आइटम के शैडो को किसी ऐसेView
के बाउंडिंग बॉक्स में छोड़ता है जिसका लिसनर, खींचे जाने के इवेंट (ड्रॉप टारगेट) पाने के लिए रजिस्टर किया गया हो. अगर उपयोगकर्ता किसी दूसरी स्थिति में खींचे गए आइटम को छोड़ता है, तो कोईACTION_DROP
खींचने का इवेंट नहीं भेजा जाता. - खत्म
जब उपयोगकर्ता, ड्रैग किए गए आइटम को छोड़ देता है और सिस्टम
ACTION_DROP
कार्रवाई टाइप के साथ एक ड्रैग इवेंट भेजता है. अगर ज़रूरी हो, तो सिस्टमACTION_DRAG_ENDED
कार्रवाई टाइप के साथ एक ड्रैग इवेंट भेजता है, ताकि यह पता चल सके कि ड्रैग-एंड-ड्रॉप ऑपरेशन खत्म हो गया है. ऐसा तब भी किया जाता है, जब उपयोगकर्ता ड्रैग शैडो को कहीं भी छोड़ता है. यह इवेंट, ड्रैग इवेंट पाने के लिए रजिस्टर किए गए हर लिसनर को भेजा जाता है. भले ही, लिसनर कोACTION_DROP
इवेंट भी मिले.
इनमें से हर चरण के बारे में ज़्यादा जानकारी, ड्रैग-एंड-ड्रॉप ऑपरेशन सेक्शन में दी गई है.
ड्रैग इवेंट
सिस्टम, DragEvent
ऑब्जेक्ट के तौर पर एक ड्रैग इवेंट भेजता है. इसमें एक ऐक्शन टाइप होता है, जो बताता है कि ड्रैग-एंड-ड्रॉप प्रोसेस में क्या हो रहा है. कार्रवाई के टाइप के आधार पर, ऑब्जेक्ट में अन्य डेटा भी हो सकता है.
ड्रैग इवेंट लिसनर को DragEvent
ऑब्जेक्ट मिलता है. ऐक्शन टाइप जानने के लिए, दर्शक DragEvent.getAction()
पर कॉल करते हैं.
DragEvent
क्लास में, पहले से तय वैल्यू के हिसाब से छह वैल्यू तय की गई हैं,
जिनके बारे में टेबल 1 में बताया गया है:
टेबल 1. DragEvent के ऐक्शन टाइप
कार्रवाई का टाइप | मतलब |
---|---|
ACTION_DRAG_STARTED |
ऐप्लिकेशन, startDragAndDrop() को कॉल करता है और
ड्रैग शैडो पाता है. अगर Listener को इस कार्रवाई के लिए, खींचने और छोड़ने के इवेंट पाना जारी रखना है, तो उसे सिस्टम को बूलियन true दिखाना होगा.
|
ACTION_DRAG_ENTERED |
ड्रैग शैडो, ड्रैग इवेंट लिसनर के
View के बाउंडिंग बॉक्स में चला जाता है. जब ड्रैग शैडो, बाउंडिंग बॉक्स में आता है, तो यह पहला इवेंट ऐक्शन टाइप होता है जो लिसनर को मिलता है.
|
ACTION_DRAG_LOCATION |
ACTION_DRAG_ENTERED इवेंट के बाद भी, ड्रैग शैडो, ड्रैग इवेंट लिसनर के View के बाउंडिंग बॉक्स में मौजूद होता है.
|
ACTION_DRAG_EXITED |
ACTION_DRAG_ENTERED और कम से कम एक
ACTION_DRAG_LOCATION इवेंट के बाद, ड्रैग शैडो, ड्रैग इवेंट लिसनर के
View के बाउंडिंग बॉक्स के बाहर चला जाता है.
|
ACTION_DROP |
ड्रैग शैडो, ड्रैग इवेंट लिसनर के
View पर रिलीज़ होता है. यह ऐक्शन टाइप, View
ऑब्जेक्ट के लिसनर को सिर्फ़ तब भेजा जाता है, जब लिसनर,
ACTION_DRAG_STARTED ड्रैग इवेंट के जवाब में बोलियन
true दिखाता है. अगर उपयोगकर्ता, View पर ड्रैग शैडो को छोड़ता है, तो यह ऐक्शन टाइप नहीं भेजा जाता है. ऐसा तब होता है, जब View के लिए कोई listener रजिस्टर न किया गया हो या उपयोगकर्ता, ड्रैग शैडो को किसी ऐसी चीज़ पर छोड़ता है जो मौजूदा लेआउट का हिस्सा नहीं है.
अगर लिसनर, ड्रॉप को प्रोसेस कर लेता है, तो वह बूलियन |
ACTION_DRAG_ENDED |
सिस्टम, खींचकर छोड़ने की प्रोसेस खत्म कर रहा है. इस तरह के ऐक्शन के लिए, ACTION_DROP इवेंट होना ज़रूरी नहीं है. अगर सिस्टम ACTION_DROP भेजता है, तो ACTION_DRAG_ENDED ऐक्शन टाइप मिलने का मतलब यह नहीं है कि ड्रॉप हो गया है. ACTION_DROP के रिस्पॉन्स में मिली वैल्यू पाने के लिए, लिसनर को getResult() को कॉल करना होगा, जैसा कि टेबल 2 में दिखाया गया है. अगर कोई
ACTION_DROP इवेंट नहीं भेजा जाता है, तो
getResult() false दिखाता है.
|
DragEvent
ऑब्जेक्ट में वह डेटा और मेटाडेटा भी शामिल होता है जो आपका ऐप्लिकेशन, startDragAndDrop()
को कॉल करते समय सिस्टम को उपलब्ध कराता है. कुछ डेटा सिर्फ़ कुछ खास तरह की कार्रवाइयों के लिए मान्य है. इसकी जानकारी टेबल 2 में दी गई है. इवेंट और उनसे जुड़े डेटा के बारे में ज़्यादा जानकारी के लिए, खींचें और छोड़ें सेक्शन देखें.
टेबल 2. कार्रवाई के टाइप के हिसाब से मान्य DragEvent डेटा
getAction() value |
getClipDescription() value |
getLocalState() value |
getX() value |
getY() value |
getClipData() value |
getResult() value |
---|---|---|---|---|---|---|
ACTION_DRAG_STARTED |
✓ | ✓ | ||||
ACTION_DRAG_ENTERED |
✓ | ✓ | ||||
ACTION_DRAG_LOCATION |
✓ | ✓ | ✓ | ✓ | ||
ACTION_DRAG_EXITED |
✓ | ✓ | ||||
ACTION_DROP |
✓ | ✓ | ✓ | ✓ | ✓ | |
ACTION_DRAG_ENDED |
✓ | ✓ |
DragEvent
के तरीके getAction()
,
describeContents()
,
writeToParcel()
, और toString()
हमेशा मान्य डेटा दिखाते हैं.
अगर किसी तरीके में किसी खास तरह के ऐक्शन के लिए मान्य डेटा नहीं है, तो वह नतीजे के टाइप के आधार पर null
या 0 दिखाता है.
शैडो को खींचें और छोड़ें
खींचकर छोड़ने की कार्रवाई के दौरान, सिस्टम एक इमेज दिखाता है जिसे उपयोगकर्ता खींचता है. डेटा को एक से दूसरी जगह ले जाने के लिए, इस इमेज में खींचे और छोड़े जा रहे डेटा को दिखाया गया है. अन्य कार्रवाइयों के लिए, इमेज में खींचने और छोड़ने की कार्रवाई के कुछ हिस्से को दिखाया जाता है.
इस इमेज को ड्रैग शैडो कहा जाता है. इसे उन तरीकों से बनाया जाता है जिन्हें आपने किसी View.DragShadowBuilder
ऑब्जेक्ट के लिए तय किया है. startDragAndDrop()
का इस्तेमाल करके, खींचें और छोड़ें वाला ऑपरेशन शुरू करने पर, बिल्डर को सिस्टम को पास किया जाता है. startDragAndDrop()
के जवाब के तौर पर, सिस्टम View.DragShadowBuilder
में तय किए गए कॉलबैक तरीकों को शुरू करता है, ताकि ड्रैग शैडो मिल सके.
View.DragShadowBuilder
क्लास में दो कंस्ट्रक्टर हैं:
View.DragShadowBuilder(View)
यह कन्स्ट्रक्टर, आपके ऐप्लिकेशन के किसी भी
View
ऑब्जेक्ट को स्वीकार करता है. कन्स्ट्रक्टर,View
ऑब्जेक्ट कोView.DragShadowBuilder
ऑब्जेक्ट में सेव करता है, ताकि कॉलबैक, खींचें और छोड़ें सुविधा के लिए शैडो बना सकें. यह ज़रूरी नहीं है कि वह व्यू,View
हो जिसे उपयोगकर्ता ने खींचने की कार्रवाई शुरू करने के लिए चुना है.इस कन्स्ट्रक्टर का इस्तेमाल करने पर, आपको
View.DragShadowBuilder
को एक्सटेंड़ करने या उसके मेथड को ओवरराइड करने की ज़रूरत नहीं है. डिफ़ॉल्ट रूप से, आपको एक ऐसी ड्रैग स्हेड मिलती है जो उसView
जैसी ही दिखती है जिसे आर्ग्युमेंट के तौर पर पास किया जाता है. यह स्हेड, उस जगह के नीचे सेंटर में दिखती है जहां उपयोगकर्ता ने स्क्रीन को छुआ है.View.DragShadowBuilder()
इस कन्स्ट्रक्टर का इस्तेमाल करने पर,
View.DragShadowBuilder
ऑब्जेक्ट में कोईView
ऑब्जेक्ट उपलब्ध नहीं होता. फ़ील्ड कोnull
पर सेट किया गया है. आपकोView.DragShadowBuilder
को एक्सटेंड करना होगा और उसके तरीकों को बदलना होगा. ऐसा न करने पर, आपको एक ऐसा ड्रैग शैडो दिखेगा जो दिखता नहीं है. सिस्टम में कोई गड़बड़ी नहीं होती.
View.DragShadowBuilder
क्लास में दो तरीके हैं, जो एक साथ ड्रैग स्हेड बनाते हैं:
onProvideShadowMetrics()
startDragAndDrop()
को कॉल करने के तुरंत बाद, सिस्टम इस तरीके को कॉल करता है. इस तरीके का इस्तेमाल करके, खींचें और छोड़ें सुविधा के शैडो के डाइमेंशन और टच पॉइंट को सिस्टम पर भेजें. इस तरीके में दो पैरामीटर होते हैं:outShadowSize
:Point
ऑब्जेक्ट. ड्रैग शैडो की चौड़ाई,x
में और उसकी ऊंचाई,y
में डाली जाती है.outShadowTouchPoint
:Point
ऑब्जेक्ट. टच पॉइंट, खींचने और छोड़ने के दौरान, उपयोगकर्ता की उंगली के नीचे मौजूद ड्रैग शैडो में मौजूद जगह होती है. इसकी X पोज़िशनx
में और Y पोज़िशनy
में जाती है.onDrawShadow()
onProvideShadowMetrics()
को कॉल करने के तुरंत बाद, सिस्टम खींचने और छोड़ने पर दिखने वाला शैडो बनाने के लिए,onDrawShadow()
को कॉल करता है. इस तरीके में एक आर्ग्युमेंट होता है, जोCanvas
ऑब्जेक्ट होता है. सिस्टम,onProvideShadowMetrics()
में दिए गए पैरामीटर से इसे बनाता है. यह तरीका, दिए गएCanvas
पर ड्रैग शैडो बनाता है.
परफ़ॉर्मेंस को बेहतर बनाने के लिए, खींचें और छोड़ें सुविधा के शैडो का साइज़ छोटा रखें. किसी एक आइटम के लिए, आइकॉन का इस्तेमाल किया जा सकता है. एक से ज़्यादा आइटम चुनने के लिए, हो सकता है कि आप स्क्रीन पर पूरी इमेज के बजाय, स्टैक में आइकॉन का इस्तेमाल करना चाहें.
ड्रैग इवेंट लिसनर और कॉलबैक के तरीके
View
को खींचने और छोड़ने से जुड़े इवेंट, खींचने और छोड़ने से जुड़े इवेंट सुनने वाले उस टूल से मिलते हैं जो View.OnDragListener
को लागू करता है या व्यू के onDragEvent()
कॉलबैक तरीके से मिलते हैं. जब सिस्टम किसी तरीके या लिसनर को कॉल करता है, तो वह एक DragEvent
आर्ग्युमेंट उपलब्ध कराता है.
ज़्यादातर मामलों में, कॉलबैक तरीके के बजाय किसी लिसनर का इस्तेमाल करना बेहतर होता है. यूज़र इंटरफ़ेस डिज़ाइन करते समय, आम तौर पर View
क्लास को सब-क्लास नहीं बनाया जाता. हालांकि, कॉलबैक तरीके का इस्तेमाल करने पर, आपको उस तरीके को बदलने के लिए सब-क्लास बनाने पड़ते हैं. इसके मुकाबले, एक लिसनर क्लास लागू की जा सकती है और फिर उसका इस्तेमाल कई अलग-अलग View
ऑब्जेक्ट के साथ किया जा सकता है. इसे बिना नाम वाली इनलाइन क्लास या लैम्ब्डा एक्सप्रेशन के तौर पर भी लागू किया जा सकता है. View
ऑब्जेक्ट के लिए लिसनर सेट करने के लिए, setOnDragListener()
को कॉल करें.
इसके अलावा, onDragEvent()
के डिफ़ॉल्ट तरीके को बदला जा सकता है. इसके लिए, आपको कोई दूसरा तरीका लागू नहीं करना होगा. किसी व्यू पर OnReceiveContentListener
सेट करें. ज़्यादा जानकारी के लिए, setOnReceiveContentListener()
देखें.
इसके बाद, onDragEvent()
तरीका डिफ़ॉल्ट रूप से ये काम करता है:
startDragAndDrop()
को कॉल करने पर, true दिखाता है.अगर व्यू में खींचकर छोड़ा गया डेटा छोड़ा जाता है, तो
performReceiveContent()
कॉल करता है. डेटा कोContentInfo
ऑब्जेक्ट के तौर पर, विधि में पास किया जाता है. यह तरीकाOnReceiveContentListener
को ट्रिगर करता है.अगर खींचकर छोड़े गए डेटा को व्यू में छोड़ा जाता है और
OnReceiveContentListener
किसी कॉन्टेंट का इस्तेमाल करता है, तो यह फ़ंक्शन 'सही' दिखाता है.
खास तौर पर अपने ऐप्लिकेशन के लिए डेटा मैनेज करने के लिए, OnReceiveContentListener
तय करें. एपीआई लेवल 24 तक के साथ काम करने के लिए, OnReceiveContentListener
के Jetpack वर्शन का इस्तेमाल करें.
आपके पास View
ऑब्जेक्ट के लिए, ड्रैग इवेंट लिसनर और कॉलबैक तरीका हो सकता है. ऐसे में, सिस्टम पहले लिसनर को कॉल करता है. सिस्टम, कॉलबैक मेथड को तब तक कॉल नहीं करता, जब तक कि लिसनर false
नहीं दिखाता.
onDragEvent()
तरीके और View.OnDragListener
का कॉम्बिनेशन, टच इवेंट के साथ इस्तेमाल किए जाने वाले onTouchEvent()
और View.OnTouchListener
के कॉम्बिनेशन जैसा ही है.