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

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

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

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

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

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

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

برای فعال کردن رویدادهای کشیدن در داخل مؤلفه، اصلاح‌کننده dragAndDropSource را اضافه کنید. این تابع را به‌عنوان پارامتر می‌گیرد. در این تابع، از DragAndDropTransferData برای نمایش داده‌های قابل‌انتقال استفاده کنید. داده‌ها می‌توانند URI راه دور، داده‌های نوشتار غنی‌شده در بریده‌دان، فایل محلی، یا موارد دیگر باشند، اما همه آن‌ها باید در شیء 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 را به یک composable اختصاص دهید تا composable بتواند رویدادهای کشیدن و رها کردن را دریافت کند. اصلاح‌کننده دو پارامتر دارد: اولی به‌عنوان فیلتر عمل می‌کند و نوع داده‌ای را که اصلاح‌کننده می‌تواند بپذیرد مشخص می‌کند، و دومی داده‌ها را در یک فراخوانی برگشتی ارائه می‌دهد.

توجه داشته باشید که نمونه callback باید به‌خاطر سپرده شود. قطعه زیر نحوه به‌خاطر سپردن 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 برگردانده‌شده از Compose callback با آنچه که از روش 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