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.
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 in my Google Docs. Download the HideAndMove zip file.
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.








Recent Comments