2011-12-05 14 views
9

Estoy tratando de arrastrar y soltar una cruz en un MapView. Tengo un botón ImageView en la pantalla. Cuando lo toco, el botón desaparece y aparece un nuevo ImageView. Se supone que el nuevo ImageView se encuentra centrado bajo mi dedo hasta que lo suelte en algún lugar, pero por alguna razón el desplazamiento es incorrecto. La cruz aparece abajo, a la derecha de donde estoy tocando.Android 2.2 Haga clic y arrastre la imagen centrada en contacto

La imagen se mueve proporcionalmente, así que creo que el problema está en offset_x y offset_y que defino en la sección ACTION_DOWN. Luego, en ACTION_UP necesito createMarker(x,y) en las coordenadas correctas debajo de mi dedo, pero eso también está compensado incorrectamente.

He intentado varias formas de hacerlo centrado, y algunos son mejores que otros. Hasta ahora no he podido hacerlo funcionar sin usar números mágicos.

Tal como está, estoy usando la ubicación del clic y restando la mitad del tamaño de la imagen. Esto tiene sentido para mí. Está más cerca de corregir si restamos el tamaño de la imagen completa. He intentado varios ejemplos de la web, todos ellos adolecen de imprecisiones en la ubicación View.

¿Me puede dar algún consejo?

crosshair = (ImageView)findViewById(R.id.crosshair); 
frameLayout = (FrameLayout)findViewById(R.id.mapframe); 
params = new LayoutParams(LayoutParams.WRAP_CONTENT, 
     LayoutParams.WRAP_CONTENT); 
crosshairImage = BitmapFactory.decodeResource(getResources(), R.drawable.crosshair); 
crosshair.setOnTouchListener(new OnTouchListener() { 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      dragStatus = START_DRAGGING; 

      // hide the button and grab a mobile crosshair 
      v.setVisibility(View.INVISIBLE); 
      image = new ImageView(getBaseContext()); 
      image.setImageBitmap(crosshairImage); 

      // set the image offsets to center the crosshair under my touch 
      offset_x = (int)event.getRawX() - (int)(crosshairImage.getWidth()/2) ; 
      offset_y = (int)event.getRawY() - (int)(crosshairImage.getHeight()/2) ; 

      // set the image location on the screen using padding 
      image.setPadding(offset_x, offset_y, 0, 0); 

      // add it to the screen so it shows up 
      frameLayout.addView(image, params); 
      frameLayout.invalidate(); 

      if(LOG_V) Log.v(TAG, "Pressed Crosshair"); 
      return true; 
     } else if (event.getAction() == MotionEvent.ACTION_UP) { 
      if(dragStatus == START_DRAGGING) { 
       dragStatus = STOP_DRAGGING; 

       // place a marker on this spot 
       makeMarker((int)event.getX() + offset_x, (int)event.getY() + offset_y); 

       // make the button visible again 
       v.setVisibility(View.VISIBLE); 

       // remove the mobile crosshair 
       frameLayout.removeView(image); 

       if(LOG_V) Log.v(TAG, "Dropped Crosshair"); 
       return true; 
      } 
     } else if (event.getAction() == MotionEvent.ACTION_MOVE) { 
      if (dragStatus == START_DRAGGING) { 
       // compute how far it has moved from 'start' offset 
       int x = (int)event.getX() + offset_x; 
       int y = (int)event.getY() + offset_y; 

       // check that it's in bounds 
       int w = getWindowManager().getDefaultDisplay().getWidth(); 
       int h = getWindowManager().getDefaultDisplay().getHeight(); 
       if(x > w) 
        x = w; 
       if(y > h) 
        y = h; 

       // set the padding to change the image loc 
       image.setPadding(x, y, 0 , 0); 

       // draw it 
       image.invalidate(); 
       frameLayout.requestLayout(); 

       if(LOG_V) Log.v(TAG, "(" + offset_x + ", " + offset_y + ")"); 

       return true; 
      } 
     }    
     return false; 
    } 

}); 
+0

Todavía estoy en busca de una solución a esto, por alguna razón no puedo encontrar una manera de mantener el punto de mira centrado debajo de mi dedo. Sé que AbsoluteLayout está en desuso, pero voy a comenzar a explorar esa ruta. Publicaré si encuentro algo. – Lea

+0

¿Es que su imagen se pivota a la posición táctil – Vivekanand

+1

@ Darunda Ha encontrado la solución. Necesito ayuda por favor al respecto? –

Respuesta

0

Has escrito este código dentro de touch_Down.

offset_x = (int)event.getRawX() - (int)(crosshairImage.getWidth()/2) ; 
offset_y = (int)event.getRawY() - (int)(crosshairImage.getHeight()/2) ; 

// set the image location on the screen using padding 
image.setPadding(offset_x, offset_y, 0, 0); 

Trate de escribirlo fuera de las condiciones if, solo para asegurarse de que se aplica a todos los eventos táctiles.

0

Puede utilizar la nueva API disponible en arrastrar y soltar

public boolean onTouch(View view, MotionEvent motionEvent) { 
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view); 
view.startDrag(null, shadowBuilder, view, 0); 
view.setVisibility(View.INVISIBLE); 
return true; 
} else { 
return false; 
} 
}