드래그 앤 드롭

Jetpack Compose는 다음 두 가지 수정자를 사용하여 드래그 앤 드롭을 지원합니다.

  • dragAndDropSource: 드래그 동작의 시작점으로 컴포저블을 지정합니다.
  • dragAndDropTarget: 드롭된 데이터를 허용하는 컴포저블을 지정합니다.

수정자를 사용하면 앱이 View 구현과 상호 운용 가능한 ClipData를 사용하여 둘 이상의 컴포저블 간에 데이터를 공유할 수 있습니다.

드래그 이벤트 시작

구성요소 내에서 드래그 이벤트를 사용 설정하려면 정지 함수를 매개변수로 사용하는 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를 반환해야 합니다.

드래그 앤 드롭 이벤트 처리

UI 및 앱 동작을 정밀하게 제어하기 위해 드래그 앤 드롭 이벤트가 언제 구성요소에서 시작, 종료, 들어가거나 종료되는지 관찰할 수 있도록 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에서 드래그 앤 드롭