Thursday, July 29, 2010

implement drag and drop on android

Nowadays, drag and drop is a frequently seen feature on touch screen devices. Tthis post introduces the basic idea of how to implement drag and drop on android.

On android, touch event is composed of a series events.
First, user puts his finger on an element, and the element receives a ACTION_DOWN event.
Then, while holding finger on screen, user moves his finger to a new location. The element receives a series of ACTION_MOVE events.
Finally, user raises his finger. At this point, the element receives ACTION_UP event.
Consider the figure below, the parent element has a child element inside. User can drag the child element anywhere in parent.

There are two important traits of touch event on android.
First, touch event will be propagated. That is, if a child chooses to ignore the first event (ACTION_DOWN) by returning false in its onTouchEvent handler, the parent's onTouchEvent handler will receive the event. Unless one of the ancestors agrees to handle the event or the root is reached, the event will continually be propagated.
Second, parent can intercept the touch event before its child's onTouchEvent handler is fired. This is achieved by overriding the onInterceptTouchEvent method on parent, and returning true from it. As a consequence, the child's onTouchEvent handler will be bypassed, and the parent's onTouchEvent handler will fire.
The work flow is shown in below diagram:


We need to setup the onTouchEvent handler for both child and parent. In child's handler, we save the child element as the item to be dragged, and return false so that subsequent event will be delivered to parent's handler. In parent's handler, we change the child's margin to match the position of the finger, so the child will follow our finger.

Sample code:
http://code.google.com/p/rxwen-blog-stuff/source/browse/#svn/trunk/android/drag

Reference:
http://developer.android.com/guide/topics/ui/ui-events.html

6 comments:

Anonymous said...

this is not a good way to implement. I tried and found that child will no longer get further events once return false (and after ACTION_UP). the source code is very easy to understand on this issue. what i have done is to always allow child to handle the drag and zoom. it works very well without parent involved.

SCC said...

Wow!! You two are way to smart. I'm just trying to learn how to drag and drop with my android 2.2 Lg touchscreen phone. And after reading this I'm more lost than ever! Lol. Like I said you two are way to smart on these things to be posting on one page. You both should be teaching this stuff or atleast getting paid big money somewhere.

Anonymous said...

How about if there are two or more images, how will you implement this? Please help... I'm new to programming and android. Thanks in advance :)

Anonymous said...

With more images to drag and drop, you need to determine which image the user has selected by getting the coordinates from the ACTION_DOWN event.

ragupathi said...

Hi im new one for android. im develop now drag and drop its very useful to me,But i need to shift the views like when i touch one view to drag and drop to another view these two views can be exchange the position. if any idea please share with me. one more thing i dont need onTouch listener instead of i need onLongClicklistner.

Thanks in andvace

christina said...

I am having problem dragging and dropping images out from one layout to another layout. Anyone can help me?