Jetpack Compose поддерживает перетаскивание с двумя модификаторами:
-
dragAndDropSource
: указывает компонуемый объект в качестве отправной точки жеста перетаскивания. -
dragAndDropTarget
: указывает компонуемый объект, который принимает переброшенные данные.
Например, чтобы пользователи могли перетаскивать изображения в вашем приложении, создайте составное изображение и добавьте модификатор dragAndDropSource
. Чтобы настроить цель перетаскивания, создайте другое компонуемое изображение и добавьте модификатор dragAndDropTarget
.
Модификаторы можно применять к нескольким источникам перетаскивания и нескольким целям перетаскивания.
Модификаторы позволяют приложениям обмениваться данными между двумя или более составными объектами с помощью ClipData
, который совместим с реализациями View
.
Начать событие перетаскивания
Чтобы включить события перетаскивания внутри компонента, добавьте модификатор dragAndDropSource
, который принимает в качестве параметра функцию приостановки. Функция определяет взаимодействие пользователя, которое запускает операцию перетаскивания. Модификатор dragAndDropSource
ждет, пока не получит событие ввода указателя, а затем выполняет лямбда-выражение, переданное обработчику событий. Используйте лямбду для обнаружения различных событий ввода, например касаний или длительных нажатий. Дополнительные сведения см. в разделе Ввод указателя в 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. См. список констант представления для получения исчерпывающего списка доступных флагов.
Получить данные о сбросе
Назначьте модификатор 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 }
Дополнительные ресурсы
Codelab: перетаскивание в Compose