ב-Jetpack Compose יש תמיכה בגרירה ושחרור עם שני משתני אופן פעולה:
dragAndDropSource
: מציין רכיב מורכב כנקודת ההתחלה של מחווה ההזזהdragAndDropTarget
: מציין רכיב מורכב שמקבל את הנתונים שהוטלו
לדוגמה, כדי לאפשר למשתמשים לגרור תמונה באפליקציה, יוצרים רכיב מורכב של תמונה ומוסיפים את המשתנה dragAndDropSource
. כדי להגדיר יעד להעברה, יוצרים עוד רכיב תמונה מורכב ומוסיפים את המשתנה dragAndDropTarget
.
אפשר להחיל את המשתנים על כמה מקורות גרירה ועל כמה יעדים להשלכה.
המשתנים מאפשרים לאפליקציות לשתף נתונים בין שני רכיבים או יותר באמצעות ClipData
, שיש לו יכולת פעולה הדדית עם הטמעות של View
.
ציון מקור גרירה
כדי להפעיל אירועי גרירה בתוך רכיב, מוסיפים את המשתנה המשנה dragAndDropSource
.
הפונקציה מקבלת פונקציה כפרמטר. בפונקציה הזו, משתמשים ב-DragAndDropTransferData
כדי לייצג את הנתונים שאפשר להעביר. הנתונים יכולים להיות URI מרוחק, נתוני טקסט עשיר בלוח העריכה, קובץ מקומי ועוד, אבל כולם צריכים להיות עטופים באובייקט ClipData
. מציינים טקסט פשוט, לדוגמה:
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( ClipData.newPlainText( "image Url", url ) ) }
כדי לאפשר לפעולה של גרירה לחצות את גבולות האפליקציה, ה-constructor של DragAndDropTransferData
מקבל ארגומנטים מסוג flags
. בדוגמה הבאה, הקבוע DRAG_FLAG_GLOBAL
מציין שאפשר לגרור נתונים מאפליקציה אחת לאפליקציה אחרת:
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( ClipData.newPlainText( "image Url", url ), flags = View.DRAG_FLAG_GLOBAL ) }
DragAndDropTransferData
מקבל דגלים שנתמכים במערכת התצוגה של Android.
רשימה מקיפה של הדגלים הזמינים מופיעה ברשימת הקבועים של View.
קבלת נתוני ירידה
כדי לאפשר לרכיב ה-Composable לקבל אירועי גרירה ושחרור, מקצים לו את המשתנה המשנה dragAndDropTarget
. למשתנה יש שני פרמטרים: הראשון משמש כמסנן ומציין את סוג הנתונים שהמשתנה יכול לקבל, והשני מעביר את הנתונים בקריאה חוזרת (callback).
שימו לב שצריך לזכור את מופע הקריאה החוזרת. קטע הקוד הבא מראה איך לשמור את הקריאה החוזרת:
val callback = remember { object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { // Parse received data return true } } }
כדי לקבל נתונים מאפליקציות אחרות, משתמשים בסמל requestDragAndDropPermission
כדי להפעיל את הקבלה, ושולחים אותו חזרה כשמסיימים:
val externalAppCallback = remember { object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { val permission = activity.requestDragAndDropPermissions(event.toAndroidDragEvent()) // Parse received data permission?.release() return true } } }
חשוב לזכור שה-DragAndDropEvent
שמוחזר מהקריאה החוזרת (callback) של Compose שונה מה-requestDragAndDropPermission
שמצופה בשיטה, לכן צריך לקרוא לפונקציית התוסף toAndroidDragEvent()
על הפרמטר לפני שמעבירים אותו לבקשת ההרשאה.
קטע הקוד הבא מדגים איך מטפלים בטקסט פשוט שנמחק:
Modifier.dragAndDropTarget( shouldStartDragAndDrop = { event -> event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN) }, target = callback // or externalAppCallback )
פונקציית הקריאה החוזרת צריכה להחזיר את הערך true
אם האירוע נצרך, או את הערך false
אם האירוע נדחה ולא הופץ לרכיב ההורה.
טיפול באירועי גרירה ושחרור
כדי לשלוט בצורה מדויקת בממשק המשתמש ובהתנהגות האפליקציה, אפשר לשנות את ברירת המחדל של פונקציות ה-callbacks בממשק DragAndDropTarget
כדי לדעת מתי אירוע גרירה ושחרור מתחיל, מסתיים, נכנס או יוצא מרכיב:
object : DragAndDropTarget { override fun onStarted(event: DragAndDropEvent) { // When the drag event starts } override fun onEntered(event: DragAndDropEvent) { // When the dragged object enters the target surface } override fun onEnded(event: DragAndDropEvent) { // When the drag event stops } override fun onExited(event: DragAndDropEvent) { // When the dragged object exits the target surface } override fun onDrop(event: DragAndDropEvent): Boolean = true }
מקורות מידע נוספים
Codelab: גרירה ושחרור ב-Compose