Thread
#compose
    j

    Jamie Craane

    1 year ago
    I am starting to experiment with drag and drop in compose. A view is made draggable by implementing the dragGestureListener and then modifying the x and y offset to the view can be dragged across the screen (is this the correct way). There are several views on which the view can be dragged-on. See the screenshot below. What is the preferred way of detecting the target view the view is dropped on? I have included some sample code.
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            var deleted by mutableStateOf(false)
            val x = mutableStateOf(0f)
            val y = mutableStateOf(0f)
    
            val colors = listOf(Color.Green, Color.Gray, Color.Blue)
    
            setContent {
                DragAndDropTestTheme {
                    Surface(color = MaterialTheme.colors.background) {
                        Column() {
    //                        This row contains potential drop targets
                            Row(
                                modifier = Modifier
                                    .height(150.dp)
                                    .fillMaxWidth()) {
                                colors.map {
                                    Box(
                                        modifier = Modifier.background(it).weight(1f).fillMaxHeight()
                                    )
                                }
                            }
                            Box(
                                modifier = Modifier.fillMaxWidth().fillMaxHeight()
                                    .background(Color.Magenta)
                            ) {
                                if (!deleted) {
                                    Box(
                                        modifier = Modifier
                                            .offsetPx(x, y)
                                            .background(Color.Cyan).width(75.dp).height(75.dp)
                                            .dragGestureFilter(object : DragObserver {
                                                override fun onDrag(dragDistance: Offset): Offset {
                                                    val newY = y.value + dragDistance.y
                                                    x.value = x.value + dragDistance.x
                                                    y.value = newY
                                                    return dragDistance
                                                }
    
                                                override fun onStop(velocity: Offset) {
                                                    // Todo what is the best method of determining what box the component is dragged on
                                                }
                                            })
                                    ) {
                                        Text(text = "Dragme", modifier = Modifier.align(Alignment.Center))
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    After some further investigation I might be able to do something like this using the Modifier.onPositioned which gives a LayoutCoordinates object. I am going to tryout that route and will update this thread with my results.