Moving Views In Android – Part 2, Drag and Drop

This is part 2 of my investigation into how to get views on an Android screen that a user can move by touching them and dragging them. For Moving Views in Android – Part 1, I had a couple of images positioned on the screen and got the images to move on the screen. It turns out that the views themselves were not moving, just the images within the bounds of the view. In the work that I describe here, I actually have the views moving. The key was to have a custom ViewGroup to coordinate drag and drop events for all views within the layout.

The figures below show what the app looks like in the emulator. Figure 1 shows the initial state of the app. Two images and a text view are in the upper left of the screen. The other figures show the views being dragged around the screen. Red highlighting indicates which view is moving.

Figures 1-2

Dragging an image

Figures 3-4:

Dragging the second image Moving the text view

The solution feels pretty good — and it should, considering it is derived from the Android Launcher code. I had searched a long time for good touch and drag-drop examples, and never found any that were as complete as what the Android developers had done. What I like is the good object model and the clear separation of responsibilities among the classes. More on that follows in the next section.

(For more on drag-drop, see “Drag-Drop for Android GridView V4“.) 

How It Works

The Launcher is the activity that manages the workspace you see on your Android phone. Besides being able to launch apps, it allows you to change the layout of icons on the screen. You touch an icon, wait for the feedback (vibration and the change in size of the icon) that you have touched a moveable icon, and then you reposition the icon on the screen.

I made a few simplifying assumptions as I built my example activity object.

  1. The example app allows you to move views, but only on a single screen. The Launcher allows you to place app icons on many screens that you get to by scrolling left and right.
  2. The example app supports only one place where you can drop views. The Launcher supports multiple DropTargets.
  3. The example app allows views to be dropped anywhere, even on top of another view. The Launcher maintains a grid of icons and icons can be dropped only in the grid.
  4. The Launcher has animation and scaling code that is used to show a bitmap of the view being moved. The example app simply shows the bitmap.

The following classes have been adapted for my example DragView application.

DragActivity – The Launcher class was turned into my DragActivity class. It is the main activity of the app.

DragLayer – implements a custom ViewGroup, which coordinates movement of views on the screen. The Launcher DragLayer is a subclass of FrameLayout. Mine is a subclass of MyAbsoluteLayout, which is a clone of the recently deprecated AbsoluteLayout class. AbsoluteLayouts allow views to be positioned to specific absolute x and y positions.

DragController – This object is the controller that does most of the work to support dragging and dropping.

DragSource – defines where a drag operation begins.

DropTarget – defines where an object can be dropped.

DragView – This is the view that you see moving around on the screen during a drag operation. It is not the actual view you want to move, but simply a bitmap that looks like the view.

In this object model, here is how an object moves on the screen. The user touches a view on the screen. The view touched signals an event, onLongClick, to its listener, which is the DragActivity. The activity turns it over to its DragController object. The controller initiates a drag operation by first getting a bitmap copy of the view, storing it in a DragView, and displaying it on the screen. As the user moves the view, the DragLayer fields all the touch events in its onTouchEvent method. It relays those events to the DragController. It watches for the end of the touch (ACTION_UP), but in the mean time, it handles the motion events by shifting the DragView to the new touch position. When the touch finally ends, the controller checks its set of DropTargets to see which one is active and if it will accept the view being dropped there. If it does, the controller calls the onDrop method of the target. In this application, the DragLayer also implements the DropTarget interface. So the onDrop call goes to the DragLayer and it takes the view being dragged and repositions it to the drop location.

The full source code is available below. A few code sections are worth noting now.

Each view that can be moved relays its onLongClick events to the DragActivity. The connection is made in the setupViews method of DragActivity.

private void setupViews() {
...
ImageView i1 = (ImageView) findViewById (R.id.Image1);
ImageView i2 = (ImageView) findViewById (R.id.Image2);
i1.setOnLongClickListener(this);
i2.setOnLongClickListener(this);
...
}

The onLongClick handler calls on the DragController to initiate the drag sequence.

public boolean onLongClick(View v) {
    trace ("onLongClick in view: " + v);
    // Let the DragController initiate a drag-drop sequence.
    // Use the dragInfo to pass along the object being dragged.
    Object dragInfo = v;
    mDragController.startDrag (v, mDragLayer, dragInfo, DragController.DRAG_ACTION_MOVE);
    return true;
}

While the drag is happening, the DragLayer passes all touch events to its DragController. The onTouchEvent method in DragController moves the DragView and its bitmap. That creates the appearance of the view moving on the screen. The move method in DragView uses updateViewLayout, which causes the layout for the screen to be redone, using whatever new x-y positions are in effect.

void move(int touchX, int touchY) {
        // This is what was done in the Launcher code.
        WindowManager.LayoutParams lp = mLayoutParams;
        lp.x = touchX - mRegistrationX;
        lp.y = touchY - mRegistrationY;
        mWindowManager.updateViewLayout(this, lp);
}

At the end of the drag, the onDrop method of DragLayer is called. It repositions the actual view. Note that it too calls to updateViewLayout. That is what causes the DragLayer view to recalculate its layout and redraw all its views.

public void onDrop (DragSource source,
         int x, int y, int xOffset, int yOffset,
        DragView dragView, Object dragInfo)
{
    View v = (View) dragInfo;
    int w = v.getWidth ();
    int h = v.getHeight ();
    int left = x - xOffset;
    int top = y - yOffset;
    DragLayer.LayoutParams lp = new DragLayer.LayoutParams (w, h, left, top);
    this.updateViewLayout(v, lp);
}

Potential Improvements

My adaptation is not quite as clean as it should be. Roughly speaking, in MVC (model-view-controller) terms, the DragActivity is the model, the DragLayer is the view, and the DragController is the controller. It’s not clear to me that I have stayed true to MVC in this example. I think the handlers for click and long click events might be better off in the controller.

This example uses a clone of the deprecated AbsoluteLayout class. Now that I understand the Launcher code better, I see that it might be better in a real application to have the DragLayer view determine exactly where views are allowed to be dropped. That would be similar to the way it was done in the Launcher app. Its Workspace class allows drops only at empty spaces in a grid. (Note: I did something for GridViews. See “Drag-Drop for an Android GridView“.) 

If you want to see an example where views are added dynamically to the DragLayer, see “Moving Views In Android – Part 3: Drop Zones“. It also shows how to give users more visual feedback as objects are being dragged around the screen.

Acknowledgements

Thanks go to the Android development team. With all the code being open source, it makes it easy for all of us to learn from their designs. A post in the Android Developers group about doing drag and drop without AbsoluteLayout pointed me in the right direction.

Source Code

The source code is available as an Eclipse project. it is available in two places:  (1) download from Wglxy.com. (2) download from Google Docs.  Do a “clean build” in Eclipse if it reports errors immediately after importing the project.

If you find that the app does not build in Eclipse, be sure to do a clean build by using the “Clean” item on the Project menu. 

This work was done on a MacBook running Eclipse Galileo and Android 2.2 (API 8).  

About these ads

136 Responses to “Moving Views In Android – Part 2, Drag and Drop”


  1. 1 Macarse January 18, 2011 at 3:24 pm

    Cool post!

    I still don’t get why you decided to used a deprecated layout. Why wouldn’t you use FrameLayout?

    I would love to see part3 with rotation and resizing :)

    Enjoy.

  2. 2 blahti January 18, 2011 at 4:55 pm

    Why use AbsoluteLayout? It was the quickest solution I could come up with where I could verify that the view was being dropped exactly where it appeared on the screen. I already had the x-y coordinates from the touch event and that made it easy to use AbsoluteLayout.

    I’m still learning so that means that this isn’t necessarily tbe ideal solution. After studying the Android Launcher code, I can see now how it’s good to let the DropTarget handle the drop and place it in the view using the LayoutParams supported by that view.

    Another point is that, for the app I have been thinking about, precise placement on a graphical display seemed like the thing to do. Perhaps I could have used WindowManager.LayoutParams. That was what they used in Launcher for the DragView.

    So besides your suggestions for a Part 3, I guess I should consider reworking this to get away from AbsoluteLayout.

  3. 3 David January 23, 2011 at 5:27 am

    thx, great work here…. It took me some time to understand the Launcher code but I am beginning to see the light

    to get rid of the myabsolute, try to extend from CellLayout.
    ps Remember to call super.onInterceptTouchEvent

    In there, celllayout will store cellinfo about the current cell in the tag…

    Each view in there can store extra info put too in the set/getTag() so you can retrieve info you need later

  4. 4 finuka January 31, 2011 at 9:51 am

    thanks a lot for your post, It’s really helpful. I’m new in Android too, and I’m trying to develop my own agenda. It can looks like google calendar, and I’ve got stuck in the “movement”. I’ll try to explain. I have my own View to customize the view of a day. There you can have events (as in google calendar). I paint those events as rectangles, with text inside. And now I can be able to change the hour of an event by touching and dragging it. But I don’t know how to get that event in a suitable “thing” to follow your post. Any idea??

    • 5 blahti February 1, 2011 at 4:39 pm

      I am not sure exactly what you are asking. So all I can offer right now is a way to think about the problem.

      Questions I would ask myself:
      My example, based on the Launcher code, uses a ViewGroup subclass named DragLayer to intercept touch events for all the child views contained within it. What does your view hierarchy look like? Which view is the container for all the event views you refer to? Have you tried adding onInterceptTouchEvent and onTouchEvent methods there? (By the way, I found another bit of doc in the Javadoc for onInterceptTouchEvent that helps me now that I’m a bit further along.)

      If you already had your ViewGroup level object hooked up with those two methods, the current example would be a pretty good model for you. You could add a DragController class and have it do most of the work for tracking the movement. And you would have to take your existing event views and make sure they send click events to a handler that would initiate the drag sequence. In the example, the click is fielded by an ImageView and it calls the onLongClick handler of the DragActivity object to get that done.

      You would have to do a bit more than the example on the drop side of the code. I didn’t have any special DropTargets. I would imagine in your case that you would want to give the user visual feedback as the dragged view moves over the different places where the drop will be accepted.

      • 6 finuka March 9, 2011 at 10:26 am

        Hi! sorry for the late reply. That was really usefull. Now I have all my work almost done. The last thing is that I’m using a viewSwitcher, and I want to be able to drag an item from one view and drop in the following. For example, imagine an agenda. I have some task to be done one day, like “going to the dentist”, but I want to move it for the following day. As the views are “independant”, I’m using an static item to save the task I want to change, and inside onDraw method, if I come from a previous day, I draw the new task. But the problem is that I lose the movement. Any idea? Your previous one was really helpful.
        Thanks in advance

      • 7 blahti March 15, 2011 at 9:20 pm

        Not sure what you mean by “lose the movement”. Do you mean the view moves some and then jumps back to its original position? Or what?

      • 8 finuka March 16, 2011 at 3:26 am

        I mean I’m dragging something from the first view to the second one, but when I reach the second view, android doesn’t recognize that I was dragging on the first view, altough I havent release the finger to drop the object. In the first view, I do “long press” on a object and now I can move it vertically through the screen and change its position. If I move it horizontally, I want to switch the views with the viewswitcher, to have the following day on the screen but I also want to be able to have the object I was moving in order to put it in this day. When I change the view, I send to the new view the object I was moving but I guess this is wrong because although the new view can paint the object, I cant move it. I dont know if I’m explaining it a little bit better than the firs time, and so sorry, I know my english is a mess!

      • 9 blahti March 17, 2011 at 6:25 am

        On another post in this blog, I responded to a question that seems like it’s related to what you want to do: drag a view from one layout to another. Read http://blahti.wordpress.com/2011/02/10/moving-views-part-3/#comment-83.

  5. 10 Asim Mittal February 3, 2011 at 9:15 am

    Hey,

    Nice tutorial. I am doing something similar. Instead of an image view i have a custom view which i need to be able to drag. Unfortunately I’m running into a roadblock. Perhaps you can help me out.

    My intention is to be able to move a view whenever i click it. I have two custom views in my activity. Both are tied up to the same onClickListener. However the click event is invoked only on one of the views.

    Even when i click view2, the event targets view1 (by that i mean the View argument being sent to my onClick method is view1).

    Please email me if you can help.

    • 11 blahti February 5, 2011 at 7:52 am

      Before working on this example based on the Android Launcher, I had found several examples and tried a few of my own where I experienced the same thing you are saying. It turned out in all cases that the actual bounds of the view were much larger than what I thought they were. View1 overlapped View2 but I could not see it.

      So I would suggest temporarily adding distinct background colors to your views and see if that shows you anything.

  6. 12 Asim Mittal February 5, 2011 at 4:13 pm

    Dear Bill,

    I ran a few tests to corroborate your findings. The view infact is drawn (by default covers the entire screen) and can be restricted by using the onMeasure method.

    I had an idea – a bit complicated – but worth a shot. If we’d like to manipulate multiple views in the same screen, we must let each view act like a layer. When a touch point is received, intercept it using dispatchTouchEvent. Now our views, as you pointed out will cover a larger area than that of the canvas (which is used to draw the view. However, if we can create a “region” object that basically translates along with the canvas, we can determine the boundaries of the canvas at all times. Even when the canvas is redrawn and translates across the view, the region can accurately tell us the area occupied by the canvas on the screen

    Now we simply check which view’s region contains the touch point (x,y) and work accordingly. What is your opinion on this approach?

    Thanks for taking the time to reply. Appreciate it!

    • 13 blahti February 7, 2011 at 10:51 pm

      It does sound a bit complicated, but I don’t have all the details.

      I know I feel better about the things I am working on now that I have lined myself up with the ways View work. They are intended to make it easy to connect events with event handlers without us having to do all the work to manage events and regions on our own. Unless there was some sort of performance issue associated with having a large number of views around, I would be reluctant to design something where views behaved in nonstandard way.

  7. 14 Asim Mittal February 7, 2011 at 5:54 am

    Hey I implemented my idea… it works. And its a lot less code too… check out my tutorial on my blog. Find the source there as well.

  8. 15 Raj February 23, 2011 at 7:27 am

    Dear Bill,

    I liked this application. My use case is like this :

    1. I have to several layouts in the screen.
    2. In that i need to move the view from layout to another.

    I tried with your idea. but on drop i get the exception as the given view is not child of the draglayer.

    Please suggest me , how i can drap and drop the views across layouts.

    thx
    raj

    • 16 blahti February 23, 2011 at 11:42 pm

      This is interesting because I ran into the same thing when I did Part 3 of this series (see http://blahti.wordpress.com/2011/02/10/moving-views-part-3/). In that example, I added DropZones so there would be areas on the screen that would exhibit different behavior as a user dragged objects over them. Then, when trying to have the DropZones themselves be draggable, I ran into the same exception you mention.

      I didn’t really come up with a solution then, but I would consider two things:
      (1) move everything under one ViewGroup so all the movable views have the same parent view;
      (2) arrange to change the parent view of the view being moved when that view is dropped.

      I think #1 will work only if you no layouts nested within other layouts. That’s probably not the case for a lot of us.

      So that leaves #2 as an option. If you try that before I do, let me know if that works.

  9. 17 ashish February 25, 2011 at 4:42 am

    hello sir..
    ive been tryin many methods to implement drag n drop but none worked for me… your article was good…
    i tried implementing your method( to be frank used ur code) to my app where in a user can dynamically add views to the layout n then reposition it..
    The problem is that im being able to drag only a few pixels… if i drag it more than that it gets bak to its original position…
    couldnt understand where it was going wrong…
    any idea sir? thnq…

    • 18 blahti February 26, 2011 at 9:44 am

      That sounds like the view enclosing the view that is being dragged is too small. How large is your DragLayer view? You might try setting the background color of the DragLayer, which is what the DragController works within. Set it to something really noticeable. If it looks much smaller than you expect and if it happens to match the boundary you reach when you drag, that would be the explanation. Then you’d have to figure out why your DragLayer size is that way.

      Another possibility is that the device you are running on is not at the same API level as my example. Does my original sample code run correctly?

      • 19 ashish February 28, 2011 at 5:24 am

        Im using dragLayer inside scrollview and its size is good.. tested it with background… and tried running it in both api 8 n 9 (as im working currently on 9)
        Yes sir.. your original code works fine in both API’s…
        Im using Eclipse helios with emulator

  10. 20 ashish February 28, 2011 at 6:06 am

    Found out the problem sir…
    Im using draglayer nested inside a scrollview and horizontal scrollview…
    When i remove them and use a plain draglayer the drag n drop is working fine..
    yet to find out the reason n solution for th problem…
    thnkyou

  11. 22 bytebender April 29, 2011 at 8:37 pm

    Thanks so much for the example! Very helpful.

  12. 23 Sandy May 19, 2011 at 10:52 pm

    Its really helpful,thanks blahti ..
    I’m new to android technology.

    if I want to restrict drop functionality within the circle drawn by canvas on screen,where and how should I write functionality?

    Should I write it in estimateDropLocation in DragLayer.java?
    I can restrict drag functionality in dragLayer of main.xml by providing android:width and height?But It will restrict to Rectangle/square and my requirement is to restrict to the circle.

    Please help me to get out of this issue.

    • 24 blahti May 23, 2011 at 5:58 am

      In the DropSpot class, there are three methods you should look at: onDragEnter, onDragExit, acceptDrop. In my example, the first two are used to change the background color of the view. That gives the user visual feedback that something could be dropped there. All those methods have all the coordinates you need to know where the object being dragged is located. Using those coordinates and your circle, which is somewhere within the view, all you’d have to do is come up with the code sequence that can detect that the current point is not only within the view, but within the circle too.

      The same would go for the acceptDrop method. It returns true if it a drop will be accepted at the location indicated by the arguments. If the drop spot is enabled and if it is within the circle, return true.

      Here are a few suggestions for finding out if a point is inside a circle: http://stackoverflow.com/questions/481144/how-do-you-test-if-a-point-is-inside-a-circle

      Hope this helps.

  13. 25 ClarkXP May 28, 2011 at 7:44 pm

    Hi, thanks Blahti for this code. I have a question. Is possible set the XY position of a View object in the start of Activity?
    Sorry my english is not good. I doing a app for put a mask over a face using recognition class of android. So I need set XY position with the coordenates returned by my method.

    Please helpme!

    • 26 ClarkXP May 29, 2011 at 5:35 pm

      Hi friend. Finally I did using the next code:
      In OnCreate:

      view = (ImageView) findViewById(R.id.imageView);

      view.setOnClickListener(this);
      view.setOnLongClickListener(this);
      vto = view.getViewTreeObserver();
      vto.addOnGlobalLayoutListener(this);

      and OnGlobalLayout Listener:

      @Override
      public void onGlobalLayout() {
      // TODO Auto-generated method stub
      faceDetect(MODO_VIEW);
      view.setImageBitmap(draw(MODO_VIEW));
      MyAbsoluteLayout.LayoutParams lp=new MyAbsoluteLayout.LayoutParams(MyAbsoluteLayout.LayoutParams.WRAP_CONTENT,MyAbsoluteLayout.LayoutParams.WRAP_CONTENT,position.x,position.y);
      view.setLayoutParams(lp);

      view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
      }

      Thank you!

  14. 27 Milos June 6, 2011 at 5:29 am

    Hi,

    Can you highlight the part of code that actually draws red rectangles around the clicked image?
    I also want in my application to somehow paint the bitmap with some color when it’s being dragged.

    Thx in advance,

    Milos

    • 28 blahti June 7, 2011 at 5:45 am

      Take a look at the onDraw method in class DragView. A DragView is what we see moving on the screen. It’s not until the drag ends does the real view actually change its position.

  15. 29 Max July 2, 2011 at 6:24 pm

    Hi,
    i’m trying to use these classes to implement “moving imageviews” in my project. It works, the images are moved when touched and dragged. But i cannot find the way to start the activity with the correct layout of my application. I explain better: all the imageviews are overlapped (as in your original code), i cannot put the imageviews for example on the bottom of the screen or the second at the right of the one. It seems that DragLayer doesn’t allow using margin or relative positioning on its view childs. Do you have any solution? Thanks in advance!

    • 30 blahti July 6, 2011 at 7:40 pm

      This example is a good introduction to drag-and-drop, but it is not the best example of using layouts. DragLayer is a subclass of MyAbsoluteLayout, which is derived from the now deprecated AbsoluteLayout class. That’s where the problem arises. I have a few suggestions for you. The first is to take a look at Part 3 of this series of notes about getting views to move. Part 3 expands on this note by fleshing out the idea of Drop Zones. If you look at its layout xml, you will see that I use a RelativeLayout within the DragLayer. That or one of the other layouts is what you’ll want to use. So you will be able to place your initial images and ones you add dynamically (also shown in Part 3) within a RelativeLayout and get the flexibility you want. Then hook up your images so they send their touch events to the DragController.

      That will get the images moving, but there is a problem that needs to be solved when you end the drag. Read through the comments on Part 3 and you will see that several people have run into the problem of a View starting out inside another View inside the DragLayer. Everything is fine until you drop the view. At that point, the current code assumes that the View’s parent is the DragLayer and blows up when it tries to assign it a position there. I have not worked out a full solution, but I have made a few suggestions in those comments on several that might work. Please read those.

      There’s also the approach used in the original Android Launcher code. Stop using AbsoluteLayout and put more intelligence in the code that handles the end of drop operations. If DragLayer is not an AbsoluteLayout, you’d have to place the view with updateViewLayout using a layout params of the desired type. When I get time, I hope to work through an example like that.

      • 31 Max July 7, 2011 at 1:18 am

        Thankyou so much for your reply! I’ll try to work around your suggestions waiting for part 4 of this article ;-) Cheers

  16. 32 Deepak Singh July 20, 2011 at 8:32 am

    When i am downloaded source code and try to import it.
    It gives error of version-8 and project are not created what is the problem and what mistake i m doing.

    Thanks

    • 33 blahti July 20, 2011 at 6:56 pm

      The Android project is compiled against Android 8. Your environment is probably set up with some other version of Android. Check the Project Properties in Eclipse to see which version you are using. My properties looks like this:
      Project Properties.
      If yours is different and a version greater than 8, give it a try. Chances are good that the demo app will work. I would not, however, try with an earlier version than 8. If it does not work, you should bring up the Android SDK and AVD Manager window within Eclipse and add API level 8.

  17. 34 Marya July 22, 2011 at 6:04 am

    Hi Bill, This article was really helpful for me. I grabbed your source code to develop a part of an app. I would like to distribute the app, maybe with some ads or something. I want to be sure you allow this; you didn’t specify a license for your source. I will not be distributing the source, just the binary. – Marya

    • 35 blahti July 24, 2011 at 5:49 pm

      My intent is to help others learn about Android. Most of the source code files have this at the top:

      This is a modified version of a class from the Android Open Source Project.
      The original copyright and license information follows.

      Copyright (C) 2008 The Android Open Source Project

      Licensed under the Apache License, Version 2.0 (the “License”);
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an “AS IS” BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.

      I added that because the sources originated with the Android source code. If I understand the Apache 2.0 License correctly, you are free to do what you like with the classes you copy as long as you include that note in your source code.
      Good luck with your app.

  18. 36 Marya July 24, 2011 at 6:03 pm

    Thanks Bill! You’ve got a very helpful site! – Marya

  19. 37 DzungHoang July 24, 2011 at 9:46 pm

    Hi Mr.blahti,
    Many thanks for your post.
    I have a problem and plz help me to solve it.
    About the situation:
    - I have a DragLayer as a FrameLayout – which contains many sheets, named Workspace_screen – ViewGroup.
    - At the time a Workspace_screen is attached to Window, I get the window token and store in a global variable.

    Workspace.onAttachedToWindow() {
    super.onAttachedToWindow();
    computeScroll();
    mDragController.setWindowToken(getWindowToken());
    }

    DragController.setWindowToken(IBinder token) {
    mWindowToken = token;
    }

    - Then at the beginning of dragging action, I send this token to the DragView:
    DragController.startDrag(){

    dragView.show(mWindowToken, (int)mMotionDownX, (int)mMotionDownY);

    }

    And the problem is: while I’m dragging the view to move around the Workspace, sometimes, all the Workspace is hang up. I mean all the screen. I lost the control of screen. It can not receive any touch. But the hard key is still work, such as [Menu] key still show my customized menu but I can not touch to select any item of menu.

    And this phenomenon is really rarely.

    Do you have any idea about this phenomenon? Plz help me!

    • 38 blahti July 30, 2011 at 5:46 am

      This sounds like it will be difficult to track down. I have had something similar happen. It seemed like debugging was not giving me any insight into the problem so what I did was add a few System.out.println statements to follow the flow through the code. Then I ran the app, switched to DDMS, and made the Logcat view as large as possible. Then I tried to make the app problem show up. In my case, I saw lots of garbage collection messages so I guessed that that was why my app become unresponsive. Then I had something I could fix. I would suggest you try something like that and see if anything in the output looks odd, particularly since you are saying that the problem does not occur all the time. You might notice a difference between running fine and being non-responsive. Hope that helps.

  20. 39 Ali August 23, 2011 at 5:51 am

    hi blahti,
    can u tell me how to move those images in a grid structure…example: moving the coins in chessboard game or checker’s game…This tutorial helped me a lot but I would be more happy if you can help me out with this problem..Thank u

    • 40 blahti August 24, 2011 at 8:09 pm

      I’ve always intended to come back to this series of articles on drag-drop and do another variation based on GridView or one of the other subclasses of ViewGroup. Sorry to say that I have not done so yet. I do have a few thoughts about what I would try.

      The first suggestion I have is for you to go through Part 3, the next in my series of notes about moving views and drag-drop. In that one, I added a DropSpot class, which implemented the DropTarget interface. Inside the onDrop method there are several comments about the use of AbsoluteLayout for the DropSpot class and the DragLayer class. In fact, the most interesting stuff in DropSpot are the methods that implement the DropTarget interface. So be sure to study those and understand what’s going on.

      From there, the next step is to decide which subclass of ViewGroup you are going to use for the replacement for the superclass of the DragLayer class. Let’s say it was GridView. You would change DragLayer to extend GridView rather than MyAbsoluteLayout. Then I’d see what views were going to be in the GridView. Your adapter object for the GridView would be the one creating those. I have not tried this, but it might work out just right to take whatever the view is that goes in the grid and have it implement the DropTarget interface. The onEnter and onExit actions could do something similar to what DropSpot does: highlight the cell and turn off highlighting. The onAccept method would need a way to check to see if the cell is occupied already. DragLayer lets DragController do most of the work while the view is being dragged. The findDropTarget method there would have to be reworked to locate the view in the GridView that is going to accept the drop.

      All in all, it’s sounding a bit difficult, and I’m not altogether sure that what I’m outlining gets you there. So that means it might be good to go back and study the Android Launcher code. It supports a grid view of some sort on the home screen, as I recall, and it had a way to detect whether a cell was open. Sorry that I can’t be more helpful in this response. It certainly feels like I need to do another installment of this series.

  21. 42 NSD August 27, 2011 at 12:40 am

    Hi,
    Its a nice tutorial. Can u tell me, When 2nd image is over the 1st image, how can we move the second image when we touch on the 1st image , on first touch it has to highlight the 1st image, on second touch it has to move the 2nd image horizontal//vertical/diagonal ? Could you please help me out with the code?

    Thanks & Regards,
    NSD.

    • 43 blahti August 28, 2011 at 7:50 am

      It sounds like you will need to store information about which views are located at a given point. If you start with studying the DragActivity class and its setupViews method, you will see that the activity is set up as the click handler for all the views. The activity object in turn passes that to its DragController object, That object reacts to the events that happen as you drag an object around. It gets the View it thinks is moving right from the touch event. If you want to change which view moves on a touch event, you should consider adding some logic there that detects which view should move. Since the DragLayer is the ViewGroup that holds all the views, it seems like that would be a good object to ask which views are stored at a particular point.

      I’d also suggest taking a look at Part 3 of this series on Moving Views and drag-drop. It has a more well-developed class, DropSpot, that implements the DropTarget interface. That will probably help you as you figure out where to add the extra information to get the behavior you want. Also, read the comment just above your question here in the list comments. I made some suggestions on how to begin thinking about using a different ViewGroup for the DragLayer.

  22. 44 veljkonm October 20, 2011 at 3:50 pm

    Hi there, great tutorial, great stuff, its very useful.

    Do you have any idea, how to implement this on custom dialogs?

    • 45 blahti October 23, 2011 at 6:14 pm

      I have not tried adding drag-drop to a custom dialog yet. A quick check at the documentation on Dialogs (see the “Creating a Custom Dialog” section) makes me think that it might be easy to do. A custom dialog gets its view assigned with setContentView, and that looks like it can be any layout. So it could be a layout where you have defined the outermost view to be a DragLayer.

      By the way, if you have not seen my new note on drag-drop for Gridviews, check that too. It is an example that does not depend on the deprecated AbsoluteLayout class. It might be useful for you to see how it handles positioning of dragged objects in case the Dialog you are thinking about would not work too well with AbsoluteLayout.

  23. 46 Arie November 2, 2011 at 4:43 am

    I have question:

    I wanna move the picture by just a click and then drag, so without the longclick. how can i change that becaus i get all the time an error.

  24. 48 Bharat December 2, 2011 at 1:01 am

    Hi blahti,

    Thanks for sharing. This is really helpful tutorial for me. We have views movable in this tutorial, now can we re-size or change height/width of these views dynamically?

    Regards,
    Bharat

    • 49 blahti December 6, 2011 at 6:15 am

      I assume you are asking how to make the view being dragged larger or smaller. In this demo, you can make the image being dragged larger by changing a line in the onDrop method of DragLayer. If you change the line that sets up the final layout params to “DragLayer.LayoutParams lp = new DragLayer.LayoutParams (2*w, 2*h, left, top);”, all images get two times larger when you drop them. Within the limitations of this demo, that illustrates how to resize. Of course, you might choose to change sizes at some other time than the start of drag. More on the limitations of this demo follow.

      Please take a look at two follow-on blog articles I have done: Part 3 on Drag-Drop, Drag-Drop for GridView. The first is where I did more with DropTarget implementations. Rather than only being able to drop onto the DragLayer, it had DropSpots at various places within the DragLayer. I could imagine building an app where certain places enlarge images when dropped onto them, and others do something else to transform an image. The second one is important because I got away from depending on AbsoluteLayout, which is now deprecated. Those articles might give you some ideas on ways you could transform images (or other objects) based on where they were dropped.

      One other point about “dynamic”: both of the follow-on articles illustrate how to create movable views and place them on the screen by clicking an Add button.

  25. 50 Ali December 3, 2011 at 1:10 am

    Can you tell me how to move from one page to other buy sliding the screen..I would be thankfull if u can help me with this..

  26. 52 Ali December 15, 2011 at 3:48 am

    Hi Blahti,
    One more time I am here, My question is how can we move or Drag the text ‘up’ and ‘down’ in a list view ..and that list view is connected to the database.I want you to help me with this problem by giving your valuable opinion or by sharing any sample application..
    Regard
    Ali

    • 53 blahti December 17, 2011 at 11:08 am

      I think I have a more recent tutorial that will help you. Take a look at “Drag-Drop for a GridView“. That uses a GridView and an ImageCellAdapter (subclass of BaseAdapter). It’s not all that different from what the Android Developers website talks about in their ListView tutorial. So if you go through my article and see how it uses custom ImageView objects in the grid, I think you will be able to come up with a custom view for your list view items. The custom view will be the place where you can implement the DragSource and DropTarget interfaces to get the text in the view to change. Unlike my example, which was only concerned with display, I’m guessing that you will want to do something more than set the text in the list item. If you want something in the database to be updated that corresponds to the change on the screen, you could try to trigger it in the DropTarget methods too.

      You might find you are better off breaking this task into two parts. That usually helps me think more clearly about the problem and simplifies the debugging. Part 1 could be figuring out how to drag and drop text items from one spot in the list to another. Part 2 would involve keeping the database in sync with the changes made via drag-drop.

  27. 54 ashish December 27, 2011 at 3:07 am

    i have tried the project.. now i have a question..can i put the small image over the other at a location and save those as a single image to sd card.

  28. 56 Vivekanand December 30, 2011 at 1:42 am

    hey, i’m really new to the concept of drag and drop. I was wondering if i could drag an item say a button and drop it into a listView.

    If that is not possible i would wanna add a new list at the position where i dropped the button.

    I would be thank full if u can assist me with this

    • 57 blahti December 30, 2011 at 11:26 am

      Dragging a button around should not be that hard. If you work through the DragSource and DropTarget interfaces and the classes that implement them, you should get a feel of the work you have to do to get a button to move. The most difficult thing in the various examples I have worked through is getting the DropTarget class to handle the view being dropped (a button, in your case). Unless all of that happens inside one DragLayer view, as described in this article, you are going to run into the problem of button view having one parent when it starts and needing to have another parent at completion of the drag. See the numerous comments and questions related to that above.

      I have pointed out that this demo app suffers from using AbsoluteLayout as the parent view. That class is deprecated and you ought to look for a different way to move things around. I have looked into that a bit. See “Drag Drop for a GridView” and study that. That article is a good example of using supported view classes. You will also see that it addresses the problem of a moving a view in a situation where the parent view seems to change. There are some follow-up comments on that one that talk about how to move from the grid view to a list view, which is your concern.

      • 58 Vivekanand January 5, 2012 at 2:07 am

        Thank you for the assist.. I’m still facing problem with finding the drop position of the button. Seems like that the only constraint which is left out..

      • 59 blahti January 5, 2012 at 1:26 pm

        If you are asking how does the DropTarget implementing class know where to put the button, you could try something like what I did in the GridView demo. I used a custom ImageView class that knew what position it was on the grid. I arranged for my adapter object to fill in that extra information when it created the image cell view. I don’t know where you are dropping your buttons, but it seems like you could arrange for it to have whatever extra information it needs so it could complete the drop successfully.

  29. 60 karan soni January 1, 2012 at 11:46 pm

    hello,
    i want to drag a circle, i draw a circle but i m not able to drag a circle on image, tell me how i drag only this circle

  30. 62 Baba January 12, 2012 at 7:57 am

    Hi!
    Thanks
    This helped me lot !

  31. 63 Ashwini January 31, 2012 at 8:33 am

    hi,
    here you are dragging and dropping image.is it possible to get copy of that image and move that copy of image.I am able to get copy of image and after dropping that copy of image i m not able move that copy of image.how to move that copy of image.

    • 64 blahti February 7, 2012 at 6:41 am

      In order to move a copy of an image, you to have make sure the view holding the image has implemented the DragSource interface. All the views on the screen in this demo do that. And since you are making a copy, you need to be able to make the connection dynamically as the new object is created. This demo (part 2) did not address that, but see the two follow-up articles: Part 3: Drop Zones, Drag-Drop for a GridView. Both of them illustrate how to add objects dynamically to the screen. You will see that objects that are added implement DragSource and that the DragLayer is informed that they are on the layer.

  32. 65 C S P Nanda March 1, 2012 at 5:45 pm

    Hi
    After I drop an object to a dropSpot, how do I disable the image being dragged again ? I am trying to get a jigsaw puzzle working. Once I move one piece to destination, I don’t want that piece to be moving again.

    • 66 blahti March 3, 2012 at 7:19 am

      You could remove the onClick and onLongClick handlers associated with the ImageCell. Or you could add an extra method to the DragSource interface. What occurs to me is that DropTarget has a method acceptDrag, which the drag controller calls to ask if the target is willing to accept a dragged object. On the other source side of things, DragSource does not have a corresponding method. It does not have something like “hasSomethingToDrag”. If it did, the drag controller could make that part of the protocol for a drag. At the time a drag starts, it could ask the drag source if it has something. If not, it stop the drag before it really gets started.

  33. 67 blahti March 3, 2012 at 5:01 pm

    To anyone looking for an answer on how to start drag-drop from a single click rather than a long click see my recent post: Improved Drag-Drop for an Android GridView.

    • 68 blahti March 5, 2012 at 8:25 am

      I have updated the source code for this demo (Part 2). There is a menu item that allows you to switch between long click and click for initiating a drag operation.

  34. 69 xs March 29, 2012 at 10:28 am

    hi there, great article. helped me so much with a project. what i’m trying to do now and having problems is for the location of the image to be saved (sharedprefences) so it shows up the same position next time it loads.

    so i tried adding the code to DragLayer – OnDropCompleted – and i get this error:

    The method getSharedPreferences(String, int) is undefined for the type DragLayer

    any thoughts?

  35. 73 RK April 7, 2012 at 2:18 pm

    Hello sir,

    Thanks for a this resourceful information. Solved a major problem in my project. I need an additional assistance from your side.

    Can you please tell me how to save the position of the currently positioned images so that next time the app loads the images in the same position.
    How can i use savecontext and getcontext here?

    • 74 blahti April 9, 2012 at 5:46 am

      For small amounts of data, I have used SharedPreferences. Then I check in onCreate to see whether I create an empty screen or restore from what is there. As for what you save, it seems like you have to save the path for each image and its location. Look in the onDrop method of DragLayer. That’s where an image is positioned on the screen. If you save that information in a data structure and then save that structure to SharedPreferences after each move, that feels like everything except for something to identify the specific image that was saved. If you are moving images that are described as resources, all you would need is the image resource id. If the images come from somewhere else, like the SD card, you’d want to save the path of the image. Check the Drag-Drop note for Part 3 too. It creates new images and positions them on the screen so they can be dragged. That might help you think about what types of information are typically needed to recreate an image view when you restore the state of your app.

      • 75 RK April 22, 2012 at 3:48 am

        @blahti
        Sir, can u please provide me with little more assistance.
        public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,DragView dragView, Object dragInfo)
        {
        View v = (View) dragInfo;

        int w = v.getWidth ();
        int h = v.getHeight ();
        left = x – xOffset;
        top = y – yOffset;
        DragLayer.LayoutParams lp = new DragLayer.LayoutParams (w, h, left, top);
        this.updateViewLayout(v, lp);
        }

        so do u suggest me to store Object,left and top in a data structure and access it somewhere else?
        I wasn’t able to crack where this initial position of the images is stored. Please help me with this.

      • 76 blahti April 22, 2012 at 8:00 am

        Yes. You will need another data structure. This demo was constructed simply to show the basics of movement. In an application, there is going to be a real reason for moving things around on the screen. If your app moves images, you’d want to save something that identifies the image, its size, and location. By the way, to convince yourself that you have found the right location values, temporarily substitute something for left in “new DragLayer.LayoutParams”. Put in some fixed value or even “left * 2″. When you release a dragged object, it will jump to that final location. Some of the later demo apps on this blog might be useful to look at too, if you should find that you do not like working with absolute x and y coordinates.

  36. 77 Christian April 16, 2012 at 3:15 pm

    Good Afternoon,
    When the imgeview set the values with imgeview,setX(100) and imageview.setY(100). The program does not work correctly.

  37. 79 RK April 23, 2012 at 5:12 am

    Suppose i store the values and the position in shared preferences, Where should i use sharedpreferences again to load them back? In MyAbsoluteLayout?

  38. 81 tatebn May 17, 2012 at 7:53 pm

    I’m trying to set the layout parameters for my DragLayer in code. I keep getting a ClassCastException with that. How do I do that? Here’s my layout params.

    // Make sure it’s filling parent
    DragLayer.LayoutParams params = new DragLayer.LayoutParams(DragLayer.LayoutParams.MATCH_PARENT, DragLayer.LayoutParams.MATCH_PARENT, 0, 0);
    this.mSelectionDragLayer.setLayoutParams(params);

    • 82 blahti May 18, 2012 at 5:37 am

      Something like this: java.lang.ClassCastException: com.blahti.example.drag2.MyAbsoluteLayout$LayoutParams.
      Right?

      You cannot use AbsoluteLayout.LayoutParams in something that is not an AbsoluteLayout. Look at the layout in which your DragLayer is embedded and use LayoutParams appropriate for that kind of layout. The parent view’s layout is what matters.

      • 83 tatebn May 18, 2012 at 8:54 am

        I’m adding it as a child to a WebView. AbsoluteLayout is the only one that doesn’t crash it. What can I use other than that? I have another view added as a child for a loading screen and ViewGroup.LayoutParams works for that, but not this.

        Also, thank you so much for posting this. This very well may save my life on this project.

      • 84 blahti May 18, 2012 at 10:10 am

        It is probably a consequence of DragLayer being an AbsoluteLayout subclass. Find something you can add to the WebView dyanmically, like a FrameLayout or a LinearLayout. Then arrange for the DragLayer to be nested inside of it. You might have to use an inflater to create the view from xml.

      • 85 tatebn May 18, 2012 at 10:07 am

        Nevermind. I’m an idiot. This worked.

        // Update Layout Params
        ViewGroup.LayoutParams layerParams = this.mSelectionDragLayer.getLayoutParams();
        layerParams.height = contentHeight;
        layerParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
        this.mSelectionDragLayer.setLayoutParams(layerParams);

  39. 87 Mark M. May 30, 2012 at 11:45 pm

    Hello

    I have just completed a simple piece-dragging mechanism to use in a simple Android word puzzle game, in which the user has to move letter pieces around the screen to spell a word that matches a given displayed picture (such as C A T).
    The code required to allow the user to drag – using finger touch – the pieces (each a TextView containing a single character) around the play area (the parent RelativeView) is quite simple and brief

    public void movePieceTo (TextView txv, int x, int y) { // 120525

    Log.v(LOGTAG,”movePieceTo: ” + txv.getTag() + “: x=” + x + ” y=” + y);
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(txv.getLayoutParams());
    params.setMargins(x, y, 0, 0);
    txv.setLayoutParams(params);
    }

    public class PieceTouchListener implements OnTouchListener { // 120525

    public TextView txvDrag=null;
    public float xBgn, yBgn;

    public boolean onTouch(View v, MotionEvent evt) {

    int act = evt.getAction();
    float x = evt.getX(), y = evt.getY();
    TextView txv = (TextView)v;
    String txvDragTag = “”;
    if (txvDrag != null) txvDragTag=(String)txvDrag.getTag();

    String strMsg = “txv touched: ” + v.getTag() + ” Event: act=” + act + ” x=” + x + ” y=” + y + ” txvDrag:” + txvDragTag;
    Log.v(LOGTAG, strMsg);
    switch (act) {
    case MotionEvent.ACTION_DOWN:
    txvDrag = txv;
    txvDrag.bringToFront();
    xBgn = x; yBgn = y;
    break;
    case MotionEvent.ACTION_MOVE:
    if (txvDrag == null) break;
    if (txvDrag != txv) break;
    int xNew = (int)(txv.getLeft() + (x – xBgn));
    int yNew = (int)(txv.getTop() + (y – yBgn));
    movePieceTo(txv, xNew, yNew);
    break;
    case MotionEvent.ACTION_UP:
    txvDrag = null;
    }
    return true; // To allow MOVE and UP events to register here, not just DOWN events.
    }

    }

    In the loop in which the pieces (TextView objects) are created, in a method not shown here, each piece is assigned the above touch listener:
    txv.setOnTouchListener( new PieceTouchListener());

    All the code shown above is within the MainActivity class module. But much of it could be encapsulated into other, external classes to allow it to apply more generally.

    I have also implemented this using an AbsoluteLayout parent (modifying the movePieceTo function to suit), and it works just as well.

    Cheers!

  40. 89 Amey Gadre June 7, 2012 at 4:38 am

    Hi Bill, I am trying to drag and drop a view in android 2.1 and above with onTouchListener. Well i am able to touch and drag and drop a view, but its not a as smooth transition as i want it. Can i have guidance over here.
    I have pasted my code over here. I have a single image inside linear layout.

    package com.ameyworld.demodragproject;

    import android.app.Activity;
    import android.os.Bundle;
    import android.util.DisplayMetrics;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.widget.ImageView;
    import android.widget.LinearLayout.LayoutParams;

    public class DemoDragProjectActivity extends Activity implements OnTouchListener
    {

    int windowwidth;

    int windowheight;

    private LayoutParams layoutParams;

    private ImageView ball;

    private int buttonPosition;

    private DisplayMetrics metrics;

    @Override
    public void onCreate( Bundle savedInstanceState )
    {
    super.onCreate( savedInstanceState );
    setContentView( R.layout.main );
    metrics = getApplicationContext().getResources().getDisplayMetrics();
    windowwidth = getWindowManager().getDefaultDisplay().getWidth();
    Log.d( “DemoDragProjectActivity-onCreate”, “WindowWidth::” + windowwidth );
    windowheight = getWindowManager().getDefaultDisplay().getHeight();
    Log.d( “DemoDragProjectActivity-onCreate”, “WindowHeight::” + windowheight );

    ball = (ImageView) findViewById( R.id.ball );
    Log.d( “DemoDragProjectActivity-onCreate”, “Height ::” + buttonPosition );

    ball.setOnTouchListener( this );

    }

    public boolean onTouch( View v, MotionEvent event )
    {
    switch( v.getId() )
    {
    case R.id.ball:
    layoutParams = (LayoutParams) ball.getLayoutParams();
    switch( event.getAction() )
    {
    case MotionEvent.ACTION_DOWN:
    break;
    case MotionEvent.ACTION_MOVE:
    int y_cord = (int) event.getRawY();
    Log.d( “DemoDragProjectActivity-onTouch”, “YCord::” + y_cord );

    if( y_cord > ( windowheight – ( metrics.density * 200 ) ) )
    {
    y_cord = (int) ( windowheight – ( metrics.density * 200 ) );
    layoutParams.topMargin = (int) event.getRawY() – ( y_cord );
    }
    else
    {
    layoutParams.topMargin = y_cord – 350;
    }

    ball.setLayoutParams( layoutParams );
    break;
    default:
    break;
    }
    return true;
    }
    return true;

    }
    }

  41. 90 Crystal June 18, 2012 at 10:33 pm

    Hi, May i know how to change the position of the the image e.g. to x=50,y=100

    • 91 blahti June 19, 2012 at 8:22 am

      In code, you can do something like this:
      DragLayer.LayoutParams lp = new DragLayer.LayoutParams (w, h, left, top);
      this.updateViewLayout(v, lp);

      If you want to do this in a layout xml file, use the deprecated AbsoluteLayout object and set x and y using xml attributes.

      By the way, you might want to look at Drag-Drop for an Android GridView. It is an example of doing drag-drop that does not rely on the obsolete AbsoluteLayout class.

  42. 92 Crystal June 20, 2012 at 3:42 am

    Thanks. May i know how to allow 1 image inside 1 drop_spot only. E.g: If the drop_spot is already filled with one image, then it will not accept any other images.

    • 93 blahti June 20, 2012 at 4:42 am

      You have to put a little bit more into your drop spot so it knows it is full. Then when the DragController calls its acceptDrop method, it needs to return false to indicate that it is full. An example of this is in the GridView example I mentioned earlier.

      • 94 crystal June 23, 2012 at 9:44 am

        Hi, can you tell me what exactly i need to add to the drop spot as i not really know what to add and where to add the code in this example.

      • 95 blahti June 26, 2012 at 4:15 am

        Sorry that I cannot help more. Please study the examples already on this blog.

  43. 96 Joy June 24, 2012 at 11:35 pm

    Hi, how do i know which image is being drag and drop to which spot?

    • 97 blahti June 25, 2012 at 5:24 am

      In this particular demo, I did not do anything to identify the image. You could store something in the image view’s tag (see setTag method), or you could build a custom ImageView where you could store information. That’s what I did in Drag-Drop for GridView. Take a look at that note.

      • 98 Joy June 26, 2012 at 3:40 am

        I still not understand, can you please provide some sample code for me.Thanks.

      • 99 blahti June 26, 2012 at 4:17 am

        Sorry that I cannot help more. With the three different sample apps, you should have sufficient information to solve the particular problem you are facing in your app.

  44. 100 Rohit July 6, 2012 at 8:15 am

    Thanksssssssssss Friend. Awesome demo.

  45. 101 hiren July 13, 2012 at 12:11 am

    Really good example of drag and drop object. Can you please help the sort out the reverse scenario where user can drag from grid view and drop on single image ? [ source and target are interchanged.] Thanks

  46. 103 Umesh July 19, 2012 at 5:17 am

    Hi Mr.Blahti,
    Many thanks for your post.
    I have putted draglayer inside horizontalScrollview .
    The code works fine, it doesnt give any exception but it not able to drag the child imageview.
    Please help.
    Thanks in advance.

    • 104 blahti July 19, 2012 at 5:57 am

      Inside a ScrollView there could be problems. Where are the touch events going? If you stick with long-press (long-click) to start a drag-drop operation, you probably will not get in the way of a normal touch that starts the scrolling. If it is not working, I would suspect that the ScrollView is getting all the touch events and handling them. You have to arrange for the long-press event to get to the DragLayer and DragController.

      • 105 Tery October 24, 2012 at 10:36 pm

        Hmmm … I too am having no success with using ScrollView or HorizontalScrollView. My goal is to have a ‘canvas’ that is twice or three times as wide/tall as the device screen. A user could then scroll this canvas and then reposition the views by touching/dragging. Any ideas? Thanks in advance for any assistance.

      • 106 blahti October 25, 2012 at 6:24 am

        I started with the Android Launcher code when I did this work. It does both dragging and scrolling, which is what we experience on our Android devices when we move application icons around. To simplify things, I left out scrolling so I could concentrate on the essential elements of drag and drop. I don’t have any code to offer. I suggest getting a copy of the drag-and-drop code in the Launcher and studying that to see how they scroll the background while maintaining the drag image. You’d want the Launcher code from Android 2.2 or 2.3.3 to match this example. Though, studying the newest code would be instructive also. See Android Source code.

      • 107 blahti October 25, 2012 at 6:33 am

        Another thought on this: figure out how ScrollView works, in the sense of what methods get called to show information scrolling in response to touching the screen. Then call those same methods in DragController when it detects that it is near the bounds of what fits on the screen.

  47. 108 Vijay September 17, 2012 at 2:55 am

    Can i rotate and Zoom that image in DragView examples

  48. 110 vikas November 9, 2012 at 4:19 am

    how can i aliign those images which is placed inside the drag layers. i cannot use margin options instead padding is available but its not convienient.

    • 111 blahti November 12, 2012 at 6:49 am

      This demo app is based on the Android Launcher code from version 2.2. When I converted it, I used AbsoluteLayout (now obsolete) as the layout for the drag layer. Since then, I have done a few more demo apps, one of which uses supported layouts. See “Drag-Drop for an Android GridView“. Study it and see how it uses a GridView. That kind of layout gives you much more control over placement of images. Once you understand that one, I think you can adapt the code to whatever layout you’d like to you. It seems that you should start with a test activity where you perfect the layout and alignments you intend to use. Then add drag-drop there.

  49. 112 Spencer November 13, 2012 at 8:11 pm

    Hi blahti,

    The drag and drop series are fantastic. It really helps with my project. But now I want to use onDropCompleted() in an activity object as a callback function for different draggable UI object that I declared in the xml or added within an activity object. Because in my case, I want the drop event triggers different actions based on the UI object or the drop target object. Is it possible with a little changes to the framework you created?

    Thank you very much.

    • 113 blahti November 16, 2012 at 7:27 am

      I don’t know the specifics of your case, but it should be possible to connect the two.
      If you wanted the other object to be draggable using the code of this framework, have it implement the DragSource interface and arrange for it to be part of the DragLayer. (By the way, a cleaner example of dragging and dropping is in a later post: Drag-Drop for a GridView.)

      If you want onDropCompleted to callback into your other code, I don’t see why that would be a problem. The good thing is that by the time onDropCompleted runs, all the tricky stuff with handling touch events is over.

      Also, check the new drag-drop framework for Android. The code I have shared is based on the old Android 2.2 Launcher code.

  50. 114 Ravikant Sharma November 22, 2012 at 5:30 am

    Hi, really lots of thanks for this example, but there is problem that i want keep my images 3*3 fashion at the begining and then i want to drag and drop on the image. I am not able to set my images in 3*3 fashion. please help me out in this problem.

  51. 116 Jaxcques December 1, 2012 at 4:45 pm

    Wow, so complicated to move an image or text, amazing. Thanks for all that help I am going to need it.

  52. 117 Jacques December 1, 2012 at 5:10 pm

    Wow, once again it’s incredibly complicated to do such a small thing. It feels like you have to build the space shuttle to go to the corner store to buy some milk. I am a beginning android/java programmer, what steps would you recommend to try and understand all of this?

    • 118 blahti December 2, 2012 at 1:20 pm

      I too was amazed when I first started. I had hoped that drag-drop would be easier. Parts 1, 2, and 3 of my series on Moving Views shows the stages I went through in understanding some of the basic things about it. Since the time of this writing, Android has introduced new support for drag-drop. You should take a look at that too. See Drag-Drop.
      I have not used it yet in any of my apps, but it does seem like a good framework. There are parts of the old Launcher framework (what my work is based on) that I really like. One day I hope to adapt it to the new Android framework.

  53. 119 Jacques December 2, 2012 at 1:42 pm

    Thanks again. I will study the new Drag & Drop in the hope that things may be a little simpler.

  54. 120 asym January 14, 2013 at 5:42 am

    hi sir ,
    i have a moving object
    basically a ball moving up and down now
    i want to drag and drop this moving object on touch event and as soon as i release the mouse the ball starts moving again ie default up and down motion please help .

    asym

    • 121 blahti January 14, 2013 at 7:54 pm

      It sounds like the drag-drop operation did not end properly. If you are still working with the code in the demo app, you might check the original code and find the places that set the variable mDragging in DragController. You might have removed one of those or you might not be calling endDrag any more, which is one of the places mDragging is set to false.

  55. 122 srinivas April 13, 2013 at 1:52 pm

    Post the code for Drag and drop items from one gridview to another gridview for 2.2 api

    • 123 blahti April 14, 2013 at 10:20 am

      Is this what you are looking for? Drag-drop for a GridView.

      I built that with Android 2.3.3, but I think it will compile and run with Android 2.2. Just change set android:minSdkVersion=”8″ in AndroidManifest.xml.

      • 124 sony tran April 23, 2013 at 11:01 am

        good tutorial. thanks for post.

        I want to zoom in, zoom out in this demo “Moving Views In Android – Part 2, Drag and Drop “. let me know about this problem?

        thanks again!

      • 125 srinivas April 23, 2013 at 3:14 pm

        I need drag and drop gridview item from one gridview to another gridview for api 8. Develop for this please and post the ocde

      • 126 blahti April 24, 2013 at 4:52 am

        The current version compiles with Android 2.3.3, but I think it will compile and run with Android 2.2. Just change set android:minSdkVersion=”8″ in AndroidManifest.xml.

        If you want to have more than one GridView active in the app, all you have to do is use the code in my GridView example. In onDragStart of DragLayer, find the code that goes through the GridView children and adds them as DropTargets. With a second GridView, you could do the same.

  56. 127 Carlos Morera April 26, 2013 at 7:10 am

    Hello blahti,

    this work is just great! I´m actually trying to have some achievements using drag and drop but I can´t find the clue. I found your job some hours ago and I started to play with it, actually what I would like to achieve in is using drag and drop with and overlay button (always on top of any app ) added through WindowsManager, I thought you might have some ideas about how I should approach this issue.

    Thanks a lot.


  1. 1 Drag-Drop for an Android GridView « More Is Not Always Better Trackback on October 3, 2011 at 6:02 am
  2. 2 How do I resize Layout/View size manually or dynamically : Android Community - For Application Development Trackback on December 20, 2012 at 9:00 am
  3. 3 Creating a view for highlight or select a particular part of image? video Trackback on December 21, 2012 at 7:11 am
  4. 4 Creating a view for highlighting or selecting a particular part of image? : Android Community - For Application Development Trackback on December 21, 2012 at 7:30 am
  5. 5 Multitouch Panning and Zooming Examples for Android « More Is Not Always Better Trackback on January 7, 2013 at 7:58 am
  6. 6 How to Longtouch to drag text on bitmap moves to up, down like InstaWeather did (Android) : Android Community - For Application Development Trackback on January 24, 2013 at 12:00 am
  7. 7 Drag-Drop for Android GridView (V4) | More Is Not Always Better Trackback on March 4, 2013 at 5:06 am
  8. 8 Drag-Drop for an Android GridView | More Is Not Always Better Trackback on March 4, 2013 at 5:17 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s





Follow

Get every new post delivered to your Inbox.

Join 72 other followers

%d bloggers like this: