سحب وإفلات

يتيح تطبيق 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