גרירה ושחרור

הכלי 'Jetpack פיתוח נייטיב' תומך בגרירה ושחרור עם שני מגבילי התאמה:

  • dragAndDropSource: מציין תוכן קומפוזבילי כנקודת ההתחלה של תנועת הגרירה
  • dragAndDropTarget: מציינת תוכן קומפוזבילי שמקבל את הנתונים שהושמטו

לדוגמה, כדי לאפשר למשתמשים לגרור תמונה באפליקציה, צריך ליצור תמונה קומפוזבילית ומוסיפים את מקש הצירוף dragAndDropSource. כדי להגדיר יעד מצומצם, צריך ליצור יעד נוסף תמונה קומפוזבילית ולהוסיף את הצירוף dragAndDropTarget.

אפשר להחיל את ערכי הצירוף על כמה מקורות גרירה ועל כמה יעדים לשחרור.

מגבילי הצירוף מאפשרים לאפליקציות לשתף נתונים בין שתי תכנים קומפוזביליים או יותר באמצעות ClipData, שאפשר לבצע בו פעולה הדדית עם הטמעות של View.

התחלת אירוע גרירה

כדי להפעיל אירועי גרירה בתוך רכיב, צריך להוסיף את מקש הצירוף dragAndDropSource, שלוקחת פונקציית השעיה כפרמטר. הפונקציה מגדירה את המשתמש אינטראקציה שמתחילה את פעולת הגרירה. מקש הצירוף dragAndDropSource מחכה עד שהוא מקבל אירוע של קלט מצביע ואז מבצע את ה-lambda מועברות למטפל באירועים. השתמשו ב-lambda כדי לזהות מגוון של אירועי קלט, למשל: הקשות או לחיצות ארוכות. למידע נוסף, ראו מצביע קלט במצב 'כתיבה'.

אירוע הקלט של הסמן הוא בדרך כלל לחיצה ארוכה שמוטמעת באופן הבא:

Modifier.dragAndDropSource {
    detectTapGestures(onLongPress = {
        // Transfer data here.
    })
}

כדי להתחיל סשן של גרירה ושחרור, מפעילים את הפונקציה startTransfer(). בתוך ההיקף הזה, משתמשים בתו DragAndDropTransferData כדי לייצג את של נתונים שניתנים להעברה. הנתונים יכולים להיות URI מרוחק, נתוני טקסט עשיר לוח, קובץ מקומי ועוד, אבל את כולם צריך אובייקט ClipData. שולחים טקסט פשוט, לדוגמה:

Modifier.dragAndDropSource {
    detectTapGestures(onLongPress = {
        startTransfer(
            DragAndDropTransferData(
                ClipData.newPlainText(
                    "image Url", url
                )
            )
        )
    })
}

כדי לאפשר לפעולת הגרירה לעבור את גבולות האפליקציה, constructor של DragAndDropTransferData מקבל ארגומנט flags. ב את הדוגמה הבאה, הקבוע DRAG_FLAG_GLOBAL מציין שהנתונים יכולים תגרום לגרירה מאפליקציה אחת לאחרת:

Modifier.dragAndDropSource {
    detectTapGestures(onLongPress = {
        startTransfer(
            DragAndDropTransferData(
                ClipData.newPlainText(
                    "image Url", url
                ),
                flags = View.DRAG_FLAG_GLOBAL
            )
        )
    })
}

DragAndDropTransferData מקבל דגלים שנתמכים על ידי מערכת Android View. צפייה את הרשימה הקבועה של View כדי לקבל רשימה מקיפה של הדגלים הזמינים.

קבלת נתוני ירידה

צריך להקצות את המגביל dragAndDropTarget לתוכן קומפוזבילי כדי להפעיל את התוכן הקומפוזבילי כדי לקבל אירועי גרירה ושחרור. למגביל יש שני פרמטרים: הראשון משמש כמסנן ומציין את סוג הנתונים שהמגביל יכול לקבל, השנייה מספקת את הנתונים בקריאה חוזרת (callback).

חשוב לזכור שצריך לזכור את המופע של הקריאה החוזרת. קטע הקוד הבא מראה איך לזכור את הקריאה החוזרת:

val callback = remember {
    object : DragAndDropTarget {
        override fun onDrop(event: DragAndDropEvent): Boolean {
            // Parse received data
            return true
        }
    }
}

קטע הקוד הבא מדגים איך לטפל בטקסט פשוט שנשמט:

Modifier.dragAndDropTarget(
    shouldStartDragAndDrop = { event ->
        event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN)
    }, target = callback
)

פונקציית הקריאה החוזרת צריכה להחזיר true אם האירוע צורך, או false אם האירוע נדחה ולא מופץ לרכיב ההורה.

איך מטפלים באירועי גרירה ושחרור

לבטל קריאות חוזרות (callback) בממשק של 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