Android: how to make a clickable map image with each country producing a different action?
Solution 1:
Here is how I solved a similar problem.
First duplicate the image that you want to use as an image map and colour each section. Needless to say, a different colour for each section :D. Then create two ImageViews in your layout. Set the background of the first one as the image that you want displayed to screen and the background of the second as the coloured in one.
Then set the visibility of the second ImageView to invisible. If you run the program at this point you should see the image that you want displayed. Then use an OnTouch listener and get the colour of the pixel where you touched. The colour will correspond to that of the coloured image.
The following getColour method would need to be passed the x and y coordinates of the touch event. R.id.img2 is the invisible image.
private int getColour( int x, int y)
{
ImageView img = (ImageView) findViewById(R.id.img2);
img.setDrawingCacheEnabled(true);
Bitmap hotspots=Bitmap.createBitmap(img.getDrawingCache());
img.setDrawingCacheEnabled(false);
return hotspots.getPixel(x, y);
}
Hope this was of some help to you :).
Solution 2:
I did it with a mask like Scotty indicated, but I ran into more problems. Basically the colors returned by getPixel were slightly different than in the mask file. What I did was to load the mask in memory with scaling disabled and with full color options like this:
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inTargetDensity = 1;
bitmapOptions.inDensity = 1;
bitmapOptions.inDither = false;
bitmapOptions.inScaled = false;
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
mask = BitmapFactory.decodeResource(appContext.getResources(), resMask, bitmapOptions);
Then I looked up the coords from the scaled image like this:
ImageView map = (ImageView) findViewById(R.id.image);
Drawable drawable = map.getDrawable();
Rect imageBounds = drawable.getBounds();
int scaledHeight = imageBounds.height();
int scaledWidth = imageBounds.width();
int scaledImageOffsetX = Math.round(event.getX()) - imageBounds.left;
int scaledImageOffsetY = Math.round(event.getY()) - imageBounds.top;
int origX = (scaledImageOffsetX * mask.getWidth() / scaledWidth);
int origY = (scaledImageOffsetY * mask.getHeight() / scaledHeight);
if(origX < 0) origX = 0;
if(origY < 0) origY = 0;
if(origX > mask.getWidth()) origX = mask.getWidth();
if(origY > mask.getHeight()) origY = mask.getHeight();
and then I applied mask.getPixel(origX, origY). It only works when the image is scaled with android:scaleType="fitXY" inside the ImageView otherwise the coords are off.