2010-10-18 7 views
18

Necesito mostrar una bonita imagen de un mapa de Europa, y quiero que mi aplicación, por ej. mostrar una actividad diferente, cuando el usuario hace clic en cada país; cada país en el mapa debe tener un onClickListener diferente (o equivalente).Android: ¿cómo hacer una imagen de mapa seleccionable con cada país produciendo una acción diferente?

Esencialmente, necesito ser capaz de llamar a una función diferente cuando el usuario toca en Francia en lugar de España en una imagen como esta: http://commons.wikimedia.org/wiki/File:Blank_map_of_Europe_cropped.svg

¿cómo iba a ir sobre esto mejor en Android?

Tengo ideas, pero puede haber alguna manera simple que estoy pasando por alto.

¡Muchas gracias de antemano!

Saludos, R3MO

+0

¿Cómo diablos sería capaz de deducir el país desde el punto de clic? En el mejor de los casos, el oyente conocería las coordenadas de la pantalla y eso es todo. No tendría idea de dónde estaban las fronteras nacionales en la pantalla – NickT

+2

De hecho, el oyente solo sabría las coordenadas en las que se hizo clic. De dos maneras: Haga que el mapa esté compuesto de muchas imágenes con oyentes, una para cada país, todas ellas superpuestas hasta cierto punto para que el mapa se vea correcto. Tal vez hay algún método para hacer esto? Alternativamente, voy a colorear cada país de forma ligeramente diferente (1 bit), para que todos tengan el mismo aspecto, pero puedo verificar el color en la coordenada de la imagen presionada y buscar en una tabla para encontrar el país al que corresponde ese color a. Aunque le agradezco que se tome el tiempo de comentar, ¿quizás alguien más puede tratar de ser más útil? – r3mo

+0

Posible duplicado de [área seleccionable de la imagen] (http://stackoverflow.com/questions/16670774/clickable-area-of-image) – lukle

Respuesta

29

Así es como he resuelto un problema similar.

Primero, duplique la imagen que desea utilizar como mapa de imagen y coloree cada sección. No hace falta decir que un color diferente para cada sección: D. Luego crea dos ImageViews en tu diseño. Establezca el fondo de la primera como la imagen que desea mostrar en la pantalla y el fondo de la segunda como el color en una.

A continuación, establezca la visibilidad del segundo ImageView en invisible. Si ejecuta el programa en este punto, debería ver la imagen que desea mostrar. Luego use un oyente OnTouch y obtenga el color del píxel donde tocó. El color se corresponderá con el de la imagen coloreada.

El siguiente método getColour debería pasar las coordenadas xey del evento táctil. R.id.img2 es la imagen invisible.

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); 
} 

Espero que esto haya sido de alguna ayuda :).

+0

¿conoce algún tutorial que tenga implementado este método, o algún código de muestra disponible? – Kgrover

+0

No funciona con Config.RGB_565, trabajó con: Bitmap.Config.ARGB_8888 – Guy

+1

@scotty cómo llegó a saber qué punto caliente se tocó si hay muchos puntos calientes en la imagen. –

2

Lo hice con una máscara como la indicada por Scotty, pero me encontré con más problemas. Básicamente, los colores devueltos por getPixel eran ligeramente diferentes que en el archivo de máscara. Lo que hice fue cargar la máscara en la memoria con la ampliación discapacitados y con opciones a todo color como este:

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); 

Luego miré hacia arriba las coordenadas de la imagen escalada como este:

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(); 

y luego Apliqué mask.getPixel (origX, origY). Solo funciona cuando la imagen se escala con android: scaleType = "fitXY" dentro de ImageView; de lo contrario, las coords están desactivadas.

1

Seguí la respuesta de clausundercover pero todavía tenía problemas con la consistencia del color del píxel en una región. Lo que finalmente funcionó para mí es asegurarme de usar una imagen PNG con indexado color para la máscara. En mi caso, utilicé la paleta optimizada para la web (216 colores) y me aseguré de que los colores elegidos fueran valores de esa paleta. Una vez que hice este cambio, obtuve el mismo valor de color en toda la región.

2

No lo he probado, pero this parece muy prometedor.

Estoy a punto de probarlo en mi proyecto, espero que funcione para ustedes.

Este tipo básicamente está tratando de emular HTML Tag Map en droide con zoom de pellizco y arrastre.

Cuestiones relacionadas