드래그 앤 드롭

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

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

예를 들어 사용자가 앱에서 이미지를 드래그할 수 있도록 하려면 이미지 컴포저블을 만들고 dragAndDropSource 수정자를 추가합니다. 드롭 타겟을 설정하려면 다른 이미지 컴포저블을 만들고 dragAndDropTarget 수정자를 추가합니다.

이 수정자는 여러 개의 드래그 소스와 여러 개의 드롭 타겟에 적용할 수 있습니다.

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

드래그 소스 지정

구성요소 내에서 드래그 이벤트를 사용 설정하려면 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 뷰 시스템에서 지원하는 플래그를 허용합니다. 사용 가능한 플래그 목록은 상수 목록을 참고하세요.

감소 데이터 수신

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
}

추가 리소스

Codelab: Compose에서 드래그 앤 드롭