مفاهیم کلیدی

بخش های زیر چند مفهوم کلیدی را برای فرآیند کشیدن و رها کردن توضیح می دهد.

فرآیند کشیدن و رها کردن

در فرآیند کشیدن و رها کردن چهار مرحله یا حالت وجود دارد: شروع، ادامه، رها و پایان.

آغاز شده

در پاسخ به حرکت کشیدن کاربر، برنامه شما 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 توضیح داده شده است:

جدول 1. انواع عمل DragEvent

نوع عمل معنی
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 که شنونده آن ثبت نشده است یا اگر کاربر سایه کشیدن را روی هر چیزی که بخشی از طرح‌بندی فعلی نیست رها کند، این نوع کنش ارسال نمی‌شود.

شنونده اگر افت را با موفقیت پردازش کند، true بولی را برمی‌گرداند. در غیر این صورت، باید false برگردد.

ACTION_DRAG_ENDED سیستم در حال پایان دادن به عملیات کشیدن و رها کردن است. این نوع کنش لزوماً دارای یک رویداد ACTION_DROP نیست. اگر سیستم یک ACTION_DROP ارسال کند، دریافت نوع اقدام ACTION_DRAG_ENDED به معنای موفقیت آمیز بودن حذف نیست. شنونده باید getResult() فراخوانی کند، همانطور که در جدول 2 نشان داده شده است، تا مقداری را که در پاسخ به ACTION_DROP برگردانده شده است، دریافت کند. اگر رویداد ACTION_DROP ارسال نشود، getResult() false را برمی‌گرداند.

شی DragEvent همچنین حاوی داده ها و ابرداده هایی است که برنامه شما در فراخوانی startDragAndDrop() به سیستم ارائه می کند. برخی از داده‌ها فقط برای انواع عملکرد خاصی که در جدول 2 خلاصه شده است معتبر هستند. برای اطلاعات بیشتر در مورد رویدادها و داده‌های مرتبط با آنها، به بخش به نام عملیات کشیدن و رها کردن مراجعه کنید.

جدول 2. داده های DragEvent معتبر بر اساس نوع عمل

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 است که برای رویدادهای لمسی استفاده می شود.