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

‫Jetpack Compose از کشیدن و رها کردن با دو اصلاح‌گر پشتیبانی می‌کند:

  • dragAndDropSource: یک عنصر ترکیبی را به‌عنوان نقطه شروع اشاره کشیدن مشخص می‌کند
  • dragAndDropTarget: یک عنصر ترکیبی را مشخص می‌کند که داده‌های رهاشده را می‌پذیرد

برای مثال، برای اینکه کاربران بتوانند تصویری را در برنامه‌تان بکشند، ترکیب‌پذیر تصویر ایجاد کنید و اصلاح‌گر dragAndDropSource را اضافه کنید. برای راه‌اندازی هدف رها کردن، ترکیب‌پذیر تصویر دیگری ایجاد کنید و اصلاح‌گر dragAndDropTarget را اضافه کنید.

اصلاح‌کننده‌ها را می‌توان برای چندین منبع کشیدن و چندین هدف رها کردن اعمال کرد.

اصلاح‌کننده‌ها به برنامه‌ها امکان می‌دهند بااستفاده از ClipData، که با پیاده‌سازی‌های View قابلیت عملکرد متقابل دارد، داده‌ها را بین دو یا چند عنصر ترکیبی هم‌رسانی کنند.

منبع کشیدن را مشخص کنید

برای فعال کردن رویدادهای کشیدن در داخل یک عنصر، اصلاح‌گر dragAndDropSource را اضافه کنید. این تابع، تابعی را به‌عنوان پارامتر می‌گیرد. درون این تابع، از DragAndDropTransferData برای نشان دادن داده‌های قابل‌انتقال استفاده کنید. داده می‌تواند نشانی وب از دور، داده نوشتار غنی در کلیپ‌بورد، فایل محلی، یا موارد دیگر باشد، اما همه آن‌ها باید در شیء ClipData پیچیده شوند. نوشتار ساده را، برای مثال، به‌صورت زیر ارائه دهید:

Modifier.dragAndDropSource { _ ->
    DragAndDropTransferData(
        ClipData.newPlainText(
            "image Url", url
        )
    )
}

برای اینکه کنش کشیدن بتواند از مرزهای برنامه عبور کند، سازنده DragAndDropTransferData آرگومان flags را می‌پذیرد. در مثال زیر، ثابت DRAG_FLAG_GLOBAL مشخص می‌کند که داده‌ها می‌توانند از یک برنامه به برنامه دیگر کشیده شوند:

Modifier.dragAndDropSource { _ ->
    DragAndDropTransferData(
        ClipData.newPlainText(
            "image Url", url
        ),
        flags = View.DRAG_FLAG_GLOBAL
    )
}

‫DragAndDropTransferData پرچم‌های پشتیبانی‌شده توسط سیستم Android View را می‌پذیرد. برای فهرست کامل پرچم‌های دردسترس، فهرست ثابت‌های نمایش را ببینید.

دریافت داده‌های قطره‌ای

اصلاح‌گر dragAndDropTarget را به یک عنصر ساختنی اختصاص دهید تا عنصر ساختنی بتواند رویدادهای کشیدن و رها کردن را دریافت کند. این اصلاح‌گر دو پارامتر دارد: پارامتر اول به‌عنوان فیلتر عمل می‌کند و نوع داده‌هایی را که اصلاح‌گر می‌تواند بپذیرد مشخص می‌کند، و پارامتر دوم داده‌ها را در یک تابع برگشتی ارائه می‌دهد.

توجه داشته باشید که نمونه تماس برگشتی باید به‌خاطر سپرده شود. تکه‌کد زیر نحوه به‌یاد آوردن پاسخ‌برگ را نشان می‌دهد:

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 برگشتی از پاسخ‌برگ Compose با requestDragAndDropPermission موردانتظار روش متفاوت است، بنابراین باید تابع افزونه toAndroidDragEvent() را روی پارامتر قبل‌از گذراندن آن به درخواست اجازه فراخوانی کنید.

تکه‌کد زیر نشان می‌دهد که چگونه می‌توان از عهده متن ساده رهاشده برآمد:

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

اگر رویداد مصرف شود، تابع فراخوانی متقابل باید 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
}

منابع بیشتر

Codelab: کشیدن و رها کردن در Compose