Moving Views in Android – Part 1

I am building an Android app where I want to have a lot of views on the screen and allow the user to move them around by touching and dragging them. I’m not there yet, but I have made some progress. So far, I have learned enough about Android touch events to get a view to move when it is touched. I’ve also learned how to hide and show views.

I have been working with ImageView objects. The app looks like Figure 1 when it starts. After a few touches (clicks in the emulator), the image views’ positions have been displaced relative to their original position. That is shown in Figure 2.

Screenshot from HideAndMoveImages in HideAndMove after a few clicks

Figures 1 – 2

How It Works

In the Android developer website, I had found an article about touch events and moving objects: Making Sense of Multitouch. It showed how to build a simple custom view that tracks touch events and moves an icon within the view. The key bit of code was in its override of the onDraw method. The method translate the position of the canvas by an x-y amount before it draws the icon that is being moved about the screen.

public void onDraw (Canvas canvas) {
   super.onDraw (canvas);
   canvas.save ();
   canvas.translate (mPosX, mPosY); 
   mIcon.draw (canvas);
   canvas.restore ();
 }

I wanted to work with ImageView objects so I did a similar thing in a custom subclass of ImageView. MyImageView has an onDraw method that looks like the following:

public void onDraw(Canvas canvas) {
  canvas.translate(mPosX, mPosY);
  super.onDraw(canvas);
}

An ImageView object already knows how to draw itself so all I had to do was translate the canvas position and call the superclass method. The instance variables mPosX and mPosY are used to keep track of the x and y displacements of the view from its original position.

I set up the HideAndMove activity so it handles any touch events on the ImageViews. It was actually a pretty simple handler. All it did was change the position of the view a little in the x and y position. It did this using the changePos method in MyImageView.

public boolean onTouch (View v, MotionEvent ev) {
  MyImageView iv = (MyImageView) v;
  float dx = 10f;
  float dy = -20f;
  iv.changePos (dx, dy);
  return false;
 }

In MyImageView there is a changePos method that takes the delta x and y values and changes the position of the view. Its code is shown below. It sets the mPosX and mPosY values and calls the invalidate method for the view. That last call is what makes the view redraw itself, and as we have already seen above, the onDraw method translates the canvas by the mPosX and mPosY values before drawing its image.

public void changePos (float dx, float dy){
  mPosX += dx;
  mPosY += dy;
  this.invalidate ();
}

That’s all I have so far for doing drag and drop on views.

Hiding images turns out to be very easy. Check the onClick handler defined in the HideAndMove activity. It has a line that changes the visibility of the first image view. I had expected this to be more difficult because I had done a few web searches and found lots of cases where Android developers were having trouble hiding and showing views in their apps.

public void onClick(View v) {
  if (mV1 != null)
    mV1.setVisibility (View.INVISIBLE); // View.GONE hides and removes view from the layout.
}

I feel like I’ve made good progress. As I’ve said in my earlier posts in this blog, I don’t know if I’ve found the absolute best way to do things, and with this particular topic, I have so much more to learn about views. If anyone has suggestions or tips, please post a comment.

For Part 2 of this project, I am going to work on the following: (1) adding a background image on which the images move; (2) getting the images to follow the touch point as it moves; (3) and having the images not be clipped by the rectangle in which they are placed.

Source Code

Source code for this example is available here: download zip file from Wglxy.com.

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.

About Bill Lahti

Bill Lahti is an indie game developer. Latest project: an exploration game. Recent game: Hop, Skip, and Thump, a simple abstract strategy game. Other iOS and Android games: Double Star II, Wing Leader, Gomoku League.
This entry was posted in Android and tagged , , . Bookmark the permalink.

11 Responses to Moving Views in Android – Part 1

  1. blahti says:

    I have made more progress on moving a view with drag-drop.

    I have been reverse-engineering the app launcher activity in Android. It defines drag layers, views, controllers, etc. It uses layout params from WindowManager, which supports absolute x and y positioning. For my examples, I have cloned the deprecated AbsoluteLayout view group and used it because it too supports x and y positioning of views.

    Overall this feels like I am heading in the right direction because the view’s size does not change. And the clickable region for the view moves with the view.

    Most of the examples I had found earlier were setting the margins for the views, creating the illusion of moving the view. Really all that was moving was the image in the view. The view’s region was getting larger. You could tell this was going on because you’d click off the image and view’s click handling code would still be activated. Not everywhere, but from the places where the left and top margins had grown.

    It’s also not clear that what I wrote above qualifies as moving the view. I’m pretty sure that the view is not moving, but the image being displayed in the view is.

    I have not finished the current experiments so there is nothing new to post here other than this comment. I intend to get the full drag-drop behavior working with multiple views before I do that.

  2. Pingback: Drag-Drop for an Android GridView « More Is Not Always Better

  3. ramesh says:

    Hello

    I’ve one issue, how can we change shadow while we are dragging, for suppose if i want to change image(after 2 sec) while the user dragging(continuously).

    • blahti says:

      You are asking a question related to Part 2 of Moving Views, right?
      The original code had a simple animation that ran along with the shadow view. Look in the startDrag method of the DragLayer class and find the lines that create a new DragView. I have not done a lot with animation, but I think you could modify that to return a view with an animation rather than a just a bitmap view.

  4. raananb says:

    I am new at Android programming, and articles like yours help in understanding this environment – quite different from C++ & wxWidgets!

    I tried to download the project source code, but there is no way to download a zip file of the whole project. Is this intentional?

    One last remark: the second line of code has a typo: ‘suoer’ instead of ‘super’

    • blahti says:

      I corrected the typo. Thanks.

      The zip file is in Google Docs (now Drive). Check the File menu near the title of the zip file. That should have a Download action.

  5. Pingback: Multitouch Panning and Zooming Examples for Android « More Is Not Always Better

  6. merry says:

    Hello blahti,

    I tried to download your source code. Google drive only answered “415. That’s an error. The requested URL was not found on this server. That’s all we know.” when trying to download the file. Did you remove it? đŸ˜¦

    • Bill Lahti says:

      There is something wrong with that page, when viewed in Google Chrome. If you click the name of the file, the download on that page does not work. However, if you click the download icon on the original page, that works just fine.
      Sorry for the inconvenience.

  7. Aamir Mehmoood says:

    its zip file is not runing with me,can you send me this project on my email in running state and mention that what i need to do change to run this in my laptop.
    aamir9595786@gamil.com

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.