سحب وإفلات

يتيح تطبيق Jetpack Compose السحب والإفلات باستخدام معدِّلَين:

  • dragAndDropSource: لتحديد عنصر قابل للإنشاء كنقطة بداية لإيماءة السحب.
  • dragAndDropTarget: لتحديد عنصر قابل للإنشاء يقبل البيانات التي تم إفلاتها

على سبيل المثال، للسماح للمستخدمين بسحب صورة في تطبيقك، عليك إنشاء صورة قابلة للإنشاء وإضافة مفتاح التعديل dragAndDropSource. لإعداد هدف انخفاض السعر، أنشِئ صورة أخرى قابلة للإنشاء وأضِف مفتاح التعديل dragAndDropTarget.

ويمكن تطبيق المُعدِّلات على مصادر سحب متعددة وأهداف إفلات متعددة.

تتيح مفاتيح التعديل للتطبيقات مشاركة البيانات بين عنصرَين أو أكثر من العناصر القابلة للإنشاء باستخدام ClipData، وهي قابلة للتشغيل التفاعلي مع عمليات تنفيذ View.

بدء حدث سحب

لتفعيل سحب الأحداث داخل المكوِّن، أضِف مفتاح التعديل dragAndDropSource الذي يأخذ دالة التعليق كمَعلمة. تحدد الدالة تفاعل المستخدم الذي يبدأ عملية السحب. ينتظر مفتاح التعديل dragAndDropSource حتى يتلقى حدث إدخال المؤشر، ثم ينفّذ دالة lambda التي تم تمريرها إلى معالج الحدث. استخدِم دالة lambda لرصد مجموعة متنوعة من أحداث الإدخال، على سبيل المثال، النقرات أو الضغطات الطويلة. لمزيد من المعلومات، يمكنك الاطّلاع على إدخال المؤشر في Compose.

عادةً ما يكون حدث إدخال المؤشر هو الضغط مع الاستمرار على النحو التالي:

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

لبدء جلسة سحب وإفلات، استدعِ الدالة startTransfer(). داخل هذا النطاق، يمكنك استخدام DragAndDropTransferData لتمثيل البيانات القابلة للتحويل. وقد تكون هذه البيانات هي معرّف موارد منتظم (URI) بعيد أو بيانات نص منسّق على الحافظة أو ملفًا على الجهاز أو غير ذلك، ولكن يجب أن تكون جميعها مضمَّنة في كائن ClipData. قدِّم نصًا عاديًا، على سبيل المثال على النحو التالي:

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

للسماح لإجراء السحب بعبور حدود التطبيق، تقبل دالة الإنشاء 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 على عنصر قابل للإنشاء لتفعيل عنصر قابل للإنشاء لتلقّي أحداث السحب والإفلات. يحتوي المُعدّل على مُعلَّمتين: الأولى تعمل كعامل تصفية وتحدد نوع البيانات التي يمكن للمُعدّلها، والثاني يسلم البيانات في استدعاء.

تجدر الإشارة إلى أنّه يجب تذكُّر مثيل معاودة الاتصال. يوضح المقتطف التالي كيفية تذكر معاودة الاتصال:

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 إذا تم رفض الحدث ولم يتم نشره إلى المكون الرئيسي.

التعامل مع أحداث السحب والإفلات

يمكنك تجاهُل عمليات الاستدعاء في واجهة 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
}

مصادر إضافية

درس تطبيقي حول الترميز: السحب والإفلات في Compose