https://kotlinlang.org logo
#compose
Title
# compose
j

Jamie Craane

10/06/2020, 6:40 AM
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.
Copy 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))
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
👍 2
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.
3 Views