I'm developing an application that would benefit from more precise control over where a dragged object is dropped. But with a capacitive touchscreen a users finger will always be obscuring the drop target.
Android allows the 'touch point' on a drag shadow to be specified by overwriting the View.DragShadowBuilder.onProvideShadowMetrics()
method. But there doesn't appear to be a way to provide a displaced 'target point'. I'd like to project an arrow from the touch-point of the drag shadow which can be maneuvered onto the drop-target with more precision.
Question: What would be the simplest / most elegant way to achieve this?
I think I could put an invisible layer over the screen during the drag operation which registers the coordinates of the touch-point, translates them and sends them to the actual drop-targets - re-implement drag-events, essentially. But I'd like to know if there is a simpler solution. Or if someone else has done something like this before.
Edit: Here's a crude mockup of the kind of drag-shadow I'd like to have:
A drag and drop operation starts when the user makes a UI gesture that your app recognizes as a signal to start dragging data. In response, the app notifies the system that a drag and drop operation is starting. The system calls back to your app to get a representation of the data being dragged (a drag shadow).
There is no direct way to do drag and drop in Android. You have to write some classes. Look into DragController. java, DragLayer.
A double tap and hold allows you to grab and then drag. A two-finger tap acts as a right click. A two-finger drag reproduces the mouse wheel scrolling action.
Question: What would be the simplest / most elegant way to achieve this?
As you already seen you can't use the View.DragShadowBuilder
class as there is no way of separating the point of the shadow handle and the point taken in consideration for all sent drag events. I also don't see another way of reimplementing the drag system, even by extending the View
class(which would be cumbersome).
I think I could put an invisible layer over the screen during the drag operation which registers the coordinates of the touch-point, translates them and sends them to the actual drop-targets - re-implement drag-events, essentially.
That is one way to do it and it's quite simple if you don't have a complicated drag and drop requirement.
But I'd like to know if there is a simpler solution.
You could probably be better off extending the basic Android layouts(at least the ones you'll use) and implement the drag logic in there. This will way you'll avoid the need for managing another layer and also doing some additional calculation. I've extended the RelativeLayout
class to implement that logic which you can find here. I've used that class in an Activity like this which has this layout. The sample is basic and it needs more work(and thinking) to make it more flexible and also solve some potential problems.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With