Spec-Zone.ru › Kotlin 2

Операции перетаскивания

Вы можете настроить приложение Compose Multiplatform так, чтобы оно принимало данные, которые пользователи перетаскивают в него из других приложений, или позволяло перетаскивать данные из вашего приложения в другие приложения. Для этого используйте модификаторы dragAndDropSource и dragAndDropTarget, чтобы указать компонуемые функции в качестве возможных источников или целей операций перетаскивания.

Модификаторы dragAndDropSource и dragAndDropTarget являются экспериментальными, могут измениться и требуют аннотации для явного согласия на использование.

Обработка данных с учётом платформы

Хотя модификаторы dragAndDropSource и dragAndDropTarget входят в общий API, передаваемые данные необходимо оборачивать в типы, специфичные для платформы:

  • Для Android оберните данные в объект ClipData из Android.

    Modifier.dragAndDropSource { _ ->
        DragAndDropTransferData(
            ClipData.newPlainText(
                "text", text
            )
        )
    }
    
  • Для iOS оберните данные в UIDragItem из UIKit.

    Modifier.dragAndDropSource {
        DragAndDropTransferData(
            listOf(UIDragItem.fromString(text)))
        }
    
  • Для настольных платформ оберните данные в datatransfer.Transferable из AWT.

    Modifier.dragAndDropSource { offset ->
        DragAndDropTransferData(
            transferable = DragAndDropTransferable(
                StringSelection(text)
            )
        )
    }
    
  • Для веб-платформы оберните данные в объект DataTransfer.

    Modifier.dragAndDropSource { _: Offset ->
        val dataTransfer = createDataTransfer()
        dataTransfer.setData("text/plain", text)
        DragAndDropTransferData(dataTransfer)
    }
    

Создание источника перетаскивания

Чтобы подготовить компонуемую функцию в качестве источника перетаскивания:

  1. Примените к компонуемой функции модификатор dragAndDropSource.

  2. (Необязательно) Добавьте лямбду drawDragDecoration, чтобы настроить визуальное представление, отображаемое во время перетаскивания данных пользователем.

  3. Верните экземпляр DragAndDropTransferData с описанием передаваемых данных, поддерживаемых действий и обработки завершения.

В следующем примере для настольной платформы компонуемая функция Box() настраивается как источник перетаскивания, предоставляющий для передачи строку. Реализация остаётся одинаковой для всех платформ, различаются только типы обёрток для данных.

val exportedText = "Hello, drag and drop!" // Measures and centers the text drawn on the drag box val textMeasurer = rememberTextMeasurer() Box(Modifier .size(200.dp) .background(Color.LightGray) .dragAndDropSource( // Creates a visual representation of the data being dragged // (white rectangle with the exportedText string centered on it). drawDragDecoration = { drawRect( color = Color.White, topLeft = Offset(x = 0f, y = size.height/4), size = Size(size.width, size.height/2) ) drawText( textMeasurer = textMeasurer, text = exportedText, topLeft = Offset(x = 16.dp.toPx(), y = size.height / 2 - 8.dp.toPx()) ) } ) { offset -> // Defines transferable data and supported transfer actions. // When an action is concluded, prints the result to // system output via onTransferCompleted(). DragAndDropTransferData( transferable = DragAndDropTransferable( StringSelection(exportedText) ), // List of actions supported by this drag source. The action type // is passed to the drop target together with the data, so // the target can reject inappropriate drops or interpret user expectations. supportedActions = listOf( DragAndDropTransferAction.Copy, DragAndDropTransferAction.Move, DragAndDropTransferAction.Link, ), dragDecorationOffset = offset, onTransferCompleted = { action -> println("Action at the source: $action") } ) } ) { Text("Drag me", Modifier.align(Alignment.Center)) }

Создание цели перетаскивания

Чтобы подготовить компонуемую функцию в качестве цели перетаскивания:

  1. Создайте объект DragAndDropTarget (и remember) с переопределениями для обрабатываемых событий перетаскивания. В нашем примере мы переопределим onStarted, onEnded и onDrop.

  2. Примените к компонуемой функции модификатор dragAndDropTarget. Передайте лямбду shouldStartDragAndDrop, которая определяет, принимает ли цель сеанс, а также объект DragAndDropTarget.

В следующем примере для настольной платформы компонуемая функция Box() настраивается как цель перетаскивания, отображающая текст, перетащенный в неё:

var showTargetBorder by remember { mutableStateOf(false) } var targetText by remember { mutableStateOf("Drop here") } val coroutineScope = rememberCoroutineScope() val dragAndDropTarget = remember { object: DragAndDropTarget { // Highlights the border of a potential drop target override fun onStarted(event: DragAndDropEvent) { showTargetBorder = true } override fun onEnded(event: DragAndDropEvent) { showTargetBorder = false } override fun onDrop(event: DragAndDropEvent): Boolean { // Prints the type of action to system output every time // a drag-and-drop operation is concluded. println("Action at the target: ${event.action}") val result = (targetText == "Drop Here") // Changes the text to the value dropped into the composable. targetText = event.awtTransferable.let { if (it.isDataFlavorSupported(DataFlavor.stringFlavor)) it.getTransferData(DataFlavor.stringFlavor) as String else it.transferDataFlavors.first().humanPresentableName } // Reverts the text of the drop target to the initial // value after 2 seconds. coroutineScope.launch { delay(2.seconds) targetText = "Drop here" } return result } } } Box(Modifier .size(200.dp) .background(Color.LightGray) .then( if (showTargetBorder) Modifier.border(BorderStroke(3.dp, Color.Black)) else Modifier ) .dragAndDropTarget( // With "true" as the value of shouldStartDragAndDrop, // drag-and-drop operations are enabled unconditionally. shouldStartDragAndDrop = { true }, target = dragAndDropTarget ) ) { Text(targetText, Modifier.align(Alignment.Center)) }

Чтобы увидеть перетаскивание в действии, разместите рядом друг с другом обе компонуемые функции Box() с указанными dragAndDropSource и dragAndDropTarget в Row():

Row(
    horizontalArrangement = Arrangement.SpaceEvenly,
    verticalAlignment = Alignment.CenterVertically,
    modifier = Modifier.fillMaxSize()
) {
    Box(Modifier.dragAndDropSource( /* ... */ )

    Box(Modifier.dragAndDropTarget( /* ... */ )
}

Что дальше

Подробные сведения о реализации и распространённых сценариях использования см. в статье Перетаскивание о соответствующих модификаторах в документации Jetpack Compose.

22 июня 2026 г.
Глубокие ссылкиВсплывающие окна

© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/multiplatform/compose-drag-drop.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API