بخش های زیر چند مفهوم کلیدی را برای فرآیند کشیدن و رها کردن توضیح می دهد.
فرآیند کشیدن و رها کردن
در فرآیند کشیدن و رها کردن چهار مرحله یا حالت وجود دارد: شروع، ادامه، رها و پایان.
- آغاز شده
در پاسخ به حرکت کشیدن کاربر، برنامه شما
startDragAndDrop()
را فراخوانی می کند تا به سیستم بگوید عملیات کشیدن و رها کردن را شروع کند. آرگومان های این روش موارد زیر را ارائه می دهند:- داده هایی که باید کشیده شوند.
- یک تماس برای ترسیم سایه کشیدن
- فراداده ای که داده های کشیده شده را توصیف می کند
- سیستم با تماس مجدد با برنامه شما برای دریافت سایه کشیدن پاسخ می دهد. سپس سیستم سایه درگ را روی دستگاه نمایش می دهد.
- در مرحله بعد، سیستم یک رویداد کشیدن با نوع عمل
ACTION_DRAG_STARTED
را به شنونده رویداد کشیدن همه اشیاءView
در طرحبندی فعلی ارسال میکند. برای ادامه دریافت رویدادهای کشیدن - از جمله یک رویداد احتمالی رها کردن - شنونده رویداد کشیدن بایدtrue
برگرداند. این کار شنونده را در سیستم ثبت می کند. فقط شنوندگان ثبت شده به دریافت رویدادهای کشیدن ادامه می دهند. در این مرحله، شنوندگان همچنین میتوانند ظاهر شیءView
drop target خود را تغییر دهند تا نشان دهند که view میتواند یک رویداد drop را بپذیرد. - اگر شنونده رویداد کشیدن،
false
برگرداند، رویدادهای کشیدن را برای عملیات جاری دریافت نمیکند تا زمانی که سیستم یک رویداد کشیدن با نوع عملACTION_DRAG_ENDED
ارسال کند. با برگرداندنfalse
، شنونده به سیستم می گوید که علاقه ای به عملیات کشیدن و رها کردن ندارد و نمی خواهد داده های کشیده شده را بپذیرد.
- ادامه دارد
- کاربر به کشیدن ادامه می دهد. همانطور که سایه کشیدن با کادر محدود یک هدف دراپ را قطع می کند، سیستم یک یا چند رویداد کشیدن را به شنونده رویداد درگ هدف ارسال می کند. شنونده ممکن است در پاسخ به رویداد ظاهر
View
هدف را تغییر دهد. به عنوان مثال، اگر رویداد نشان میدهد که سایه کشیدن وارد کادر محدودکننده هدف رها میشود - نوع عملACTION_DRAG_ENTERED
- شنونده میتواند با برجسته کردنView
واکنش نشان دهد. - کاهش یافته است
- کاربر سایه کشیدن را در کادر محدود یک هدف رها می کند. سیستم یک رویداد کشیدن با نوع کنش
ACTION_DROP
را به شنونده هدف رها میفرستد. شی رویداد drag حاوی دادههایی است که در فراخوانیstartDragAndDrop()
که عملیات را شروع میکند به سیستم ارسال میشود. در صورتی که شنونده داده های حذف شده را با موفقیت پردازش کند، انتظار می رود شنونده به سیستمtrue
بولی را برگرداند. : این مرحله تنها زمانی اتفاق میافتد که کاربر سایه کشیدن را در کادر محدود نمایView
که شنونده آن برای دریافت رویدادهای کشیدن ثبت شده است رها کند (هدف رها کردن). اگر کاربر سایه کشیدن را در هر موقعیت دیگری آزاد کند، هیچ رویداد کشیدنACTION_DROP
ارسال نمی شود. - به پایان رسید
پس از اینکه کاربر سایه درگ را آزاد کرد و پس از ارسال سیستم
یک رویداد کشیدن با نوع عمل
ACTION_DROP
، در صورت لزوم، سیستم یک رویداد کشیدن با نوع عملACTION_DRAG_ENDED
ارسال میکند تا نشان دهد که عملیات کشیدن و رها کردن به پایان رسیده است. این کار بدون توجه به جایی که کاربر سایه درگ را آزاد می کند انجام می شود. رویداد برای هر شنونده ای که برای دریافت رویدادهای کشیدن ثبت شده است ارسال می شود، حتی اگر شنونده رویدادACTION_DROP
را نیز دریافت کند.
هر یک از این مراحل با جزئیات بیشتری در بخشی به نام عملیات کشیدن و رها کردن توضیح داده شده است.
رویدادها را بکشید
سیستم یک رویداد کشیدن را به شکل یک شی DragEvent
ارسال می کند که حاوی یک نوع عمل است که آنچه را که در فرآیند کشیدن و رها کردن اتفاق می افتد توصیف می کند. بسته به نوع عمل، شی می تواند حاوی داده های دیگری نیز باشد.
شنوندگان رویداد Drag، شی DragEvent
دریافت می کنند. برای دریافت نوع عمل، شنوندگان DragEvent.getAction()
را فراخوانی می کنند. شش مقدار ممکن توسط ثابت های کلاس DragEvent
تعریف شده است که در جدول 1 توضیح داده شده است:
نوع عمل | معنی |
---|---|
ACTION_DRAG_STARTED | برنامه startDragAndDrop() را فراخوانی می کند و یک سایه درگ دریافت می کند. اگر شنونده بخواهد به دریافت رویدادهای درگ برای این عملیات ادامه دهد، باید Boolean 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 که شنونده آن ثبت نشده است یا اگر کاربر سایه کشیدن را روی هر چیزی که بخشی از طرحبندی فعلی نیست رها کند، این نوع کنش ارسال نمیشود. شنونده اگر افت را با موفقیت پردازش کند، |
ACTION_DRAG_ENDED | سیستم در حال پایان دادن به عملیات کشیدن و رها کردن است. این نوع کنش لزوماً دارای یک رویداد ACTION_DROP نیست. اگر سیستم یک ACTION_DROP ارسال کند، دریافت نوع اقدام ACTION_DRAG_ENDED به معنای موفقیت آمیز بودن حذف نیست. شنونده باید getResult() فراخوانی کند، همانطور که در جدول 2 نشان داده شده است، تا مقداری را که در پاسخ به ACTION_DROP برگردانده شده است، دریافت کند. اگر رویداد ACTION_DROP ارسال نشود، getResult() false را برمیگرداند. |
شی DragEvent
همچنین حاوی داده ها و ابرداده هایی است که برنامه شما در فراخوانی startDragAndDrop()
به سیستم ارائه می کند. برخی از دادهها فقط برای انواع عملکرد خاصی که در جدول 2 خلاصه شده است معتبر هستند. برای اطلاعات بیشتر در مورد رویدادها و دادههای مرتبط با آنها، به بخش به نام عملیات کشیدن و رها کردن مراجعه کنید.
getAction() ارزش | getClipDescription() ارزش | getLocalState() ارزش | getX() ارزش | getY() ارزش | getClipData() ارزش | getResult() ارزش |
---|---|---|---|---|---|---|
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
در شیView.DragShadowBuilder
موجود نیست. فیلد رویnull
تنظیم شده است. شما بایدView.DragShadowBuilder
را گسترش دهید و متدهای آن را لغو کنید، در غیر این صورت یک سایه کشیدن نامرئی دریافت خواهید کرد. سیستم خطا نمی دهد.
کلاس View.DragShadowBuilder
دو متد دارد که با هم سایه کشیدن را ایجاد می کنند:
-
onProvideShadowMetrics()
سیستم بلافاصله پس از فراخوانی
startDragAndDrop()
این متد را فراخوانی می کند. از روش برای ارسال ابعاد و نقطه لمس سایه درگ به سیستم استفاده کنید. روش دارای دو پارامتر است:outShadowSize
: یک شیPoint
. عرض سایه درگ بر حسبx
و ارتفاع آن بر حسبy
می شود.outShadowTouchPoint
: یک شیPoint
. نقطه لمس مکانی در سایه کشیدن است که باید در هنگام کشیدن زیر انگشت کاربر باشد. موقعیت X آن درx
و موقعیت Y آن درy
می رود.-
onDrawShadow()
بلافاصله پس از فراخوانی
onProvideShadowMetrics()
سیستمonDrawShadow()
برای ایجاد سایه کشیدن فرا می خواند. این متد یک آرگومان واحد دارد، یک شیCanvas
که سیستم از پارامترهایی که درonProvideShadowMetrics()
ارائه میکنید، میسازد. این روش سایه کشیدن را رویCanvas
ارائه شده ترسیم می کند.
برای بهبود عملکرد، اندازه سایه کشیدن را کوچک نگه دارید. برای یک مورد، ممکن است بخواهید از یک نماد استفاده کنید. برای انتخاب چند مورد، ممکن است بخواهید از نمادها در یک پشته به جای تصاویر کامل که روی صفحه پخش شده اند استفاده کنید.
شنوندگان رویداد و روشهای پاسخ به تماس را بکشید
یک View
رویدادهای کشیدن را با یک شنونده رویداد drag دریافت می کند که View.OnDragListener
یا با روش برگشت تماس onDragEvent()
view را اجرا می کند. هنگامی که سیستم متد یا شنونده را فراخوانی می کند، آرگومان DragEvent
ارائه می دهد.
در بیشتر موارد، استفاده از شنونده بر استفاده از روش بازگشت به تماس ارجحیت دارد. وقتی رابط کاربری طراحی میکنید، معمولاً کلاسهای View
را زیر کلاس نمیگذارید، اما استفاده از روش callback شما را مجبور میکند تا کلاسهای فرعی ایجاد کنید تا متد را لغو کنید. در مقایسه، میتوانید یک کلاس listener را پیادهسازی کنید و سپس از آن با چندین شی مختلف View
استفاده کنید. شما همچنین می توانید آن را به عنوان یک کلاس درون خطی ناشناس یا عبارت لامبدا پیاده سازی کنید. برای تنظیم شنونده برای یک شی View
، setOnDragListener()
را فراخوانی کنید.
به عنوان جایگزین، میتوانید اجرای پیشفرض onDragEvent()
را بدون نادیده گرفتن متد تغییر دهید. یک OnReceiveContentListener
را روی یک View تنظیم کنید. برای جزئیات بیشتر، به setOnReceiveContentListener()
مراجعه کنید. سپس متد onDragEvent()
به صورت پیش فرض کارهای زیر را انجام می دهد:
- در پاسخ به تماس
startDragAndDrop()
true را برمی گرداند. در صورتی که دادههای کشیدن و رها کردن روی نما رها شوند،
performReceiveContent()
فراخوانی میکند. داده ها به عنوان یک شیContentInfo
به متد ارسال می شوند. متدOnReceiveContentListener
را فراخوانی می کند.اگر دادههای کشیدن و رها کردن روی نما رها شوند و
OnReceiveContentListener
هر یک از محتواها را مصرف کند، درست برمیگردد.
OnReceiveContentListener
را برای مدیریت داده ها به طور خاص برای برنامه خود تعریف کنید. برای سازگاری به عقب تا سطح API 24، از نسخه Jetpack OnReceiveContentListener
استفاده کنید.
شما می توانید یک شنونده رویداد کشیدن و یک روش برگشت به تماس برای یک شی View
داشته باشید، در این صورت سیستم ابتدا شنونده را فرا می خواند. سیستم متد برگشت تماس را فراخوانی نمی کند مگر اینکه شنونده false
برگرداند.
ترکیب متد onDragEvent()
و View.OnDragListener
مشابه ترکیب onTouchEvent()
و View.OnTouchListener
است که برای رویدادهای لمسی استفاده می شود.