拖曳

Jetpack Compose 支援拖曳與放置,並提供兩種修飾符:

舉例來說,如要讓使用者在應用程式中拖曳圖片,請建立圖片可組合項並新增 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 系統支援的旗標。如需可用旗標的完整清單,請參閱 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
        }
    }
}

請務必記住,從 Compose 回呼傳回的 DragAndDropEventrequestDragAndDropPermission 方法預期的 DragAndDropEvent 不同,因此您需要在參數上呼叫 toAndroidDragEvent() 擴充功能函式,然後再將其傳遞至權限要求。

下列程式碼片段示範如何處理遺漏的純文字:

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

如果事件已取用,回呼函式應傳回 true;如果事件遭到拒絕且未傳播至父項元件,則應傳回 false

處理拖曳事件

DragAndDropTarget 介面中覆寫回呼,以便觀察拖曳事件的開始、結束時間,或元件進入或離開的時間,藉此精確控制 UI 和應用程式的行為:

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 中的拖曳功能